Brandon's Tinkerings brandon_wiki http://brandon.penglase.net/index.php?title=Main_Page MediaWiki 1.40.1 first-letter Media Special Talk User User talk Brandon's Tinkerings Brandon's Tinkerings talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Main Page 0 1 1 2012-05-30T17:15:08Z MediaWiki default 0 wikitext text/x-wiki '''MediaWiki has been successfully installed.''' Consult the [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software. == Getting started == * [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list] * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] b7a3846f2c55072191227d89a3204fe379288fee 2 1 2012-05-30T18:31:55Z Bpenglase 1 /* Getting started */ wikitext text/x-wiki '''MediaWiki has been successfully installed.''' Consult the [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software. == Getting started == * [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list] * [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] * [Special:UserRights] e90be915c41457426f7f5f1b4d48aa9d2bfb7e75 3 2 2012-05-30T18:48:07Z Bpenglase 1 Replaced content with "''' Welcome. '''" wikitext text/x-wiki ''' Welcome. ''' 6c2ba7aaa26c48242adcfb6766feba8c4dc77643 5 3 2012-05-31T00:53:46Z Bpenglase 1 wikitext text/x-wiki ''' Welcome. ''' Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work. * Computer Related Prodding * Network Wrangling * Dabbling in Electronics bbfc9c932f18949aed92dd067a8da74d93f686a2 6 5 2012-05-31T00:55:58Z Bpenglase 1 wikitext text/x-wiki ''' Welcome. ''' Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work. * [[Computer Related Prodding]] * [[Network & Systems Wrangling]] * [[Dabbling in Electronics]] 1f01972f3a2972786a957be902f8add290854595 MediaWiki:Sidebar 8 2 4 2012-05-30T18:54:54Z Bpenglase 1 Created page with " * navigation ** mainpage|mainpage-description ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help * SEARCH * TOOLBOX" wikitext text/x-wiki * navigation ** mainpage|mainpage-description ** recentchanges-url|recentchanges ** randompage-url|randompage ** helppage|help * SEARCH * TOOLBOX 3b3992950fca6cf2b1c804b675d8a6e4c6f63c8d Computer Related Prodding 0 3 7 2012-05-31T01:08:49Z Bpenglase 1 Created page with "* [[The World According to Apple]] - Ways I have found to get OS X/iOS to function in the "Enterprise" world, typically with 3rd party software. * Breaking Windows - Different..." wikitext text/x-wiki * [[The World According to Apple]] - Ways I have found to get OS X/iOS to function in the "Enterprise" world, typically with 3rd party software. * Breaking Windows - Different things I have found building Windows images and supporting Windows machines 06c95873247bbeb27f7bf6e7006973c51505f749 The World According to Apple 0 4 8 2012-05-31T01:12:01Z Bpenglase 1 Created page with "* [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images." wikitext text/x-wiki * [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images. 386c8f5bd83f11c9535f79e31b35a02ffb997d18 Getting *nix to Netboot Macs 0 5 9 2012-05-31T01:13:08Z Bpenglase 1 Created page with "<syntaxhilight lang="bash"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLB..." wikitext text/x-wiki <syntaxhilight lang="bash"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Ask for these options from the client if (option dhcp-message-type = 1) { # On DHCPDiscover Message(s) # Tell the client, via selected boot image (08:04:), which image we're preferring as default (81:00:00:89) option vendor-class-identifier "AAPLBSDPC"; option vendor-encapsulated-options 08:04:81:00:00:89; # bsdp option 8 (length 04) -- selected image id; } elsif (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name #-- Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/ipxe.efi"; next-server 10.0.3.2; option root-path = "http://boot.neltia.net/ipxe.efi"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot filename "DSRBoot.img"; next-server 10.0.3.2; option root-path = "http://osx-server.boot.neltia.net/DSRBoot.img"; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhilight> 2ffb9cf6e5419bc6066e9c5b083ec74aa53bb8e3 10 9 2012-05-31T01:23:15Z Bpenglase 1 wikitext text/x-wiki <syntaxhighlight lang="bash"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Ask for these options from the client if (option dhcp-message-type = 1) { # On DHCPDiscover Message(s) # Tell the client, via selected boot image (08:04:), which image we're preferring as default (81:00:00:89) option vendor-class-identifier "AAPLBSDPC"; option vendor-encapsulated-options 08:04:81:00:00:89; # bsdp option 8 (length 04) -- selected image id; } elsif (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name #-- Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/ipxe.efi"; next-server 10.0.3.2; option root-path = "http://boot.neltia.net/ipxe.efi"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot filename "DSRBoot.img"; next-server 10.0.3.2; option root-path = "http://osx-server.boot.neltia.net/DSRBoot.img"; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> 538d05ff4e4e1acca307b8d83195bd4e40ec5925 11 10 2012-05-31T01:37:06Z Bpenglase 1 wikitext text/x-wiki <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Ask for these options from the client if (option dhcp-message-type = 1) { # On DHCPDiscover Message(s) # Tell the client, via selected boot image (08:04:), which image we're preferring as default (81:00:00:89) option vendor-class-identifier "AAPLBSDPC"; option vendor-encapsulated-options 08:04:81:00:00:89; # bsdp option 8 (length 04) -- selected image id; } elsif (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name #-- Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/ipxe.efi"; next-server 10.0.3.2; option root-path = "http://boot.neltia.net/ipxe.efi"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot filename "DSRBoot.img"; next-server 10.0.3.2; option root-path = "http://osx-server.boot.neltia.net/DSRBoot.img"; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> 6d7a342f1fcd47a5d55b3569ed315be34e8f9e1c 12 11 2012-05-31T02:09:59Z Bpenglase 1 wikitext text/x-wiki <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> a4cca3876d1a0026ec8b433af0bee2b02a62055a 13 12 2012-05-31T03:17:51Z Bpenglase 1 wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html http://www.dolcevie.com] to convert ASCII/Strings to Hex (Image Names) 811061bbed2765ba473f8965c7ca0904065b6490 14 13 2012-05-31T03:23:14Z Bpenglase 1 /* Resources Used to Complete this */ wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times 5152e0f8c39f659c3e6c68323219cff84c923e56 15 14 2012-05-31T03:23:32Z Bpenglase 1 wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times == Fin == I have learned more about BSDP then I ever wanted to know :) 34341541944094eb312a1916b26f501a089290df 16 15 2012-05-31T03:26:53Z Bpenglase 1 wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times == Fin == * I have learned more about BSDP then I ever wanted to know :) * I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox. 77ff8e6ab761af8144ce2563350d141e1604e0ad 17 16 2012-05-31T12:45:13Z Bpenglase 1 Added line about posting to OSXDeployment wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times == Fin == * Once [http://osxdeployment.com/wiki/Main_Page OSXDeployment.com] is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference. * I have learned more about BSDP then I ever wanted to know :) * I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox. 3bc8e3d96b85b8c08df36f7df7257dd7e0a39459 Network & Systems Wrangling 0 6 18 2012-09-28T00:06:21Z Bpenglase 1 Added link for FreeRADIUS config wikitext text/x-wiki [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users. Including but not limited to: WPA2-Enterprise and EAPoL (Wireless and Wired authentication) 2493abd2c00b8d721fbc32d98b7ceacfc80e71a8 19 18 2012-09-28T00:07:18Z Bpenglase 1 Corrected wording on FreeRADIUS line. wikitext text/x-wiki [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). 7ef89dc110426c02ea46e1ac4d98b665f99ea211 34 19 2012-09-29T02:26:38Z Bpenglase 1 Added sections for cisco switches/aps wikitext text/x-wiki [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. f0ea2c97d2b888dcd2d82e98d97c9bbe5d72a288 35 34 2012-09-29T02:27:11Z Bpenglase 1 wikitext text/x-wiki [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. 1dfd9f896f9f9bdabed0e29bf74d6345f4f072a9 36 35 2012-09-29T02:27:46Z Bpenglase 1 Formatting wikitext text/x-wiki * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). * [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. * [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. 25d4d61089732d63aed75c457a8f494340ec6f16 46 36 2012-10-13T01:37:13Z Bpenglase 1 Added PXE Boot wikitext text/x-wiki * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). * [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. * [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. * [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics. 6e45470dd6c00fffc0a29b0eb33a75693fe0367d Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP 0 7 20 2012-09-28T02:37:55Z Bpenglase 1 Initial submit of the FreeRADIUS config page wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup FreeRADIUS to do 802.1x authentication. Why am I doing another? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up another page here. This was also expedited by user in the #FreeRADIUS channel looking to do the same, but as I as posting configs, it wasn't helping. So, without further ado, I give you my guide on setting up FreeRADIUS pulling it's information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from (http://www.cacert.org CACert). I do recommend them, especially if you can get assured. == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * FreeRADIUS was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me. * SSL Cert from CACert (needs to be known who the CA is when configuring it). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented 9b45d6d95a75a984f98c26696b3b239cdc8c72ba 21 20 2012-09-28T02:57:20Z Bpenglase 1 Other changes, included LDAP config, caveats, etc. wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #FreeRADIUS channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** The LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless only, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me. * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 0aea01758acd62adb712b80954e8f0238460468e 22 21 2012-09-28T02:59:12Z Bpenglase 1 /* Intro */ Corrected FreeRADIUS irc channel case. wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** The LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless only, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me. * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 7eddf5c8e888b5491252e4f321744ae5f3feeb95 23 22 2012-09-28T02:59:51Z Bpenglase 1 /* What does this page assume? */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless only, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me. * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 26191620edf215286fbd42e87227472b551d7610 24 23 2012-09-28T03:00:13Z Bpenglase 1 /* What does this page assume? */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me. * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 752f4dcdc370eb8f24e6f7f00b3f62c04400e74e 25 24 2012-09-28T03:02:10Z Bpenglase 1 /* What does this page assume? */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * I'm doing this as I write this, so if you find this in the middle of editing, sorry. Otherwise, you'll know it's complete and working for me. * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 6bde6a83938a463e8018e2f5c3ad632a2a920fb8 26 25 2012-09-28T03:03:01Z Bpenglase 1 /* My testing environment */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 53bff4d109cd57a48dd455fefdca9aa50476243f 27 26 2012-09-28T03:03:25Z Bpenglase 1 /* clients.conf */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. afa5a41583dc4802ec8eb1c32ee9ab189de041af 28 27 2012-09-28T03:04:38Z Bpenglase 1 /* clients.conf */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc). <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * Added: checkItem Cleartext-Password userPassword ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. d97a00838adeb496022c23a614f35d0a3c83ced4 29 28 2012-09-28T03:05:37Z Bpenglase 1 /* ldap.attrmap */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc). <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * checkItem Cleartext-Password userPassword -- Added at bottom ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. 8e7122d40b1ff01f8369b0fc3550611122a822cf 30 29 2012-09-28T03:07:39Z Bpenglase 1 /* modules/ldap */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc). <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * checkItem Cleartext-Password userPassword -- Added at bottom ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment *** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP) ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. e5435c9f32d1958f6db0206aa0199bf6035c19d5 31 30 2012-09-28T03:20:12Z Bpenglase 1 added a lot, and resources. wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc). <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * checkItem Cleartext-Password userPassword -- Added at bottom ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment *** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP) ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. ** As such, I highly recommend doing TLS on LDAP, since otherwise you might end up with passwords going over the wire in clear-text. * I know some of the stuff in LDAP isn't fully clear, or some of the more advanced stuff like VLAN assignment. I'll try to clear these up later, but for right now, this should get you up and going. == Resources used == * Sadly I set the majority of this up a long time ago, but I do seem to have some bookmarks, so I'll throw some of them here. Otherwise, I only used one recently from the FreeRADIUS mailing list. * http://vuksan.com/linux/dot1x/802-1x-LDAP.html -- Good guide, also covers setting up OpenLDAP and it's ACLs, and device setup. * http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius * [http://wiki.freeradius.org/Home The FreeRADIUS Wiki] * http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg48720.html -- Email through bookmarked. == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. Sometimes I am in the #freeradius channel, sometimes not, but I am usually connected. * http://lists.freeradius.org/pipermail/freeradius-users/2012-January/058185.html -- This thread, specially this post to get the Dynamic VLAN assignment working. 9b9922edac4b344ec220a7a628c78af098564195 32 31 2012-09-28T03:22:47Z Bpenglase 1 wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc). <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * checkItem Cleartext-Password userPassword -- Added at bottom ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment *** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP) ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. ** As such, I highly recommend doing TLS on LDAP, since otherwise you might end up with passwords going over the wire in clear-text. * I know some of the stuff in LDAP isn't fully clear, or some of the more advanced stuff like VLAN assignment. I'll try to clear these up later, but for right now, this should get you up and going. == Resources used == * Sadly I set the majority of this up a long time ago, but I do seem to have some bookmarks, so I'll throw some of them here. Otherwise, I only used one recently from the FreeRADIUS mailing list. * http://vuksan.com/linux/dot1x/802-1x-LDAP.html -- Good guide, also covers setting up OpenLDAP and it's ACLs, and device setup. * http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius * [http://wiki.freeradius.org/Home The FreeRADIUS Wiki] * http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg48720.html -- Email thread bookmarked. * http://lists.freeradius.org/pipermail/freeradius-users/2012-January/058185.html -- This thread, specially this post to get the Dynamic VLAN assignment working. == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. Sometimes I am in the #freeradius channel, sometimes not, but I am usually connected. 274917adf79dafc932c896ad24aff642d3aa7189 33 32 2012-09-28T03:25:23Z Bpenglase 1 /* Resources used */ wikitext text/x-wiki == Intro == You guessed correctly. This is yet another article on how to setup [http://freeradius.org/ FreeRADIUS] to do [http://en.wikipedia.org/wiki/IEEE_802.1X 802.1x authentication]. Why am I doing another when there are a plethora of other such guides out there? Well, the others I found lacking. When I set this up a few years ago, I remember having at least 10 different HowTo's/Guides/FAQs open. Recently in my studies I needed to debug something with FreeRADIUS (was not working with Dynamic VLAN assignment), and I got thinking: Where exactly does FreeRADIUS kick over authentication to LDAP? Since I couldn't recall, I figured I would make up a guide, and redo the configuration to better understand it. This was also expedited by user in the #freeradius FreeNode channel looking to do the same, but as I as posting configs, it wasn't helping. This will get you to a place where you can do User and MAC address authentication, and Dynamic VLAN Assignment (or 802.1x VLAN assignment) So, without further ado, I give you my guide on setting up FreeRADIUS, pulling authentication information from an LDAP backend. == What does this page assume? == * You have a working OpenLDAP setup. ** The FreeRADIUS machine does need /etc/openldap/ldap.conf configured correctly, at least if you are doing TLS for LDAP. ** There's a few good guides out there, and this isn't terribly difficult. I may come up with something later, in which case I'll link to it at that time. ** Passwords are stored in plain text ** My LDAP tree is setup as such: *** ou=Wireless,ou=Services,dc=domain,dc=com -- Where the RADIUS settings are stored (I originally set this up for Wireless, hence the name) **** ou=Machines,ou=Wireless -- Where Machine MAC addresses are stored, with uid=001122334455, and password of the same **** ou=Users,ou=Wireless -- Where users are stored. Note, the passwords here are in plain-text, so it needs protected via LDAP ACLs ** I highly suggest [http://directory.apache.org/studio/ Apache Directory Studio] to manage the LDAP Database, if you don't already have something graphical. * You have configured your end devices (or will once FreeRADIUS is setup). ** In my case, my wireless AP is a Cisco AP-1242AG, and the LAN switches I have tested this on are: 2950-24T, 2950G-48, 3750-48PS, 3550-24-PWR. The configuration for these devices is fairly simple and well documented on Cisco's website. Using another manufacture shouldn't be much different, as RADIUS/EAP is standards based. * You have Server SSL Certs. I won't go in to this much, as SSL is it's own beast, but I got my wildcard certs from [http://www.cacert.org CACert]. I do recommend them, especially if you can get assured. You can also setup your own CA for SSL Certs ( I think this is recommended by FreeRADIUS). == My testing environment == * Linux, Distro: Gentoo Hardened, AMD64 Stable (Note: SELinux was disabled on this machine) ** While some stuff may be Gentoo specific, the basics of the files in the /etc/raddb (FreeRADIUS's config directory on Gentoo) should be the same across the board * freeradius-2.1.11-r1 was emerged with the following USE line: ** USE="ldap mysql pam snmp ssl threads udpfromto -bindist -debug -edirectory (-firebird) -frascend -frxp -kerberos -postgres" Adjust as needed, but you will need at least 'ldap' and 'ssl'. ** You can do this with: echo "net-dialup/freeradius ldap mysql pam snmp ssl threads udpfromt" >> /etc/portage/package.use/freeradius * SSL Cert from CACert (needs to be known who the CA is when configuring it). This is needed for the EAP stuff, not just TLS to LDAP (it's actually not used there). == The Files == * All files are referenced from /etc/raddb/ === clients.conf === * Only modification here was adding the client stanza at the bottom. In my case, I did one stanza to cover most of my devices. If you want more fine-grain control, you can specify each one as a /32. This is for the device that you are connecting to (e.g. AP, Switch, etc). <syntaxhighlight lang="bash"> client 10.0.3.64/28 { secret = testing1234 } </syntaxhighlight> === eap.conf === * Under EAP {}: ** default_eap_type = peap ** Under TLS {}: *** This section says not to use a known CA, but this is where I use my cert from CACert, so known or not is up for debate. *** pem_file_type = yes -- This is an addition *** certdir = /etc/ssl/<domain>_wildcard -- This is where I store the wildcard cert mentioned above *** cadir = /etc/ssl/certs -- since CACert is included in the system CAs *** #private_key_password = whatever -- Commented this out, as my privkey has no password (a pain with Apache) *** private_key_file = ${certdir}/<domain>_wildcard.key *** certificate_file = ${certdir}/<domain>_wildcard.crt *** CA_file = ${cadir}/cacert.org.pem *** #CA_path = ${cadir} -- Commented out, maybe this is fine? ** Under peap {}: *** use_tunneled_reply = yes -- This is only needed for Dynamic VLAN Assignment. For straight Auth, you don't need to change this === ldap.attrmap === * checkItem Cleartext-Password userPassword -- Added at bottom ** I haven't tried to modify this to include the normal hashed password used for system authentication, which requires bouncing through something like ntlm_auth. So, for now, as explained above, I store the password in plaintest, in a ACL protected OU. === modules/ldap === * Under ldap {}: ** server = "server.domain.com" -- set to your LDAP Server ** identity = "cn=radius,ou=virtual,ou=users,dc=domain,dc=com" -- Set to your RADIUS LDAP user, or some other user that can access the stuff in your OU below ** password = "MyradiusUserPassword" ** basedn = "ou=Wireless,ou=Services,dc=domain,dc=com" -- The OU where your RADIUS stuff is stored. I explained this above for my layout. ** #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" -- Commented, as everything under the DN above is RADIUS, so I don't need to filter. ** Under tls {}: *** start_tls = yes -- My LDAP Server is setup for TLS, and I prefer to use it in all instances connecting to it. *** cacertdir = /etc/ssl/certs -- Uncomment, letting it use the system root CAs. *** require_cert = "demand" -- Uncomment *** Remember if you configure TLS to also setup /etc/openldap/ldap.conf too (basic configuration if you have a machine authing against LDAP) ** access_attr_used_for_allow = yes -- Uncomment ** set_auth_type = no -- Uncommented and changed === modules/mschap === * Under mschap {}: ** authtype = MS-CHAP -- Addition ** use_mppe = yes -- Uncommented and changed ** require_encryption = yes -- Uncommented ** require_strong = yes -- Uncommented ** with_ntdomain_hack = yes -- Uncommented and changed * Note: sites-enabled only had the default files symlinked inside (control-socket, default, inner-tunnel) === sites-enabled/default === * Under authorize {}: ** #chap -- Commented ** #digest -- Commented ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented ** #pap -- Commented * Under authenticate {}: ** #Auth-Type CHAP {} -- Section commented ** #digest -- Commented ** #unix -- Commented === sites-enabled/inner-tunnel === * Under server inner-tunnel {}: ** #listen {} -- Commented listen block * Under authorize {}: ** unix -- Uncommented - Old? ** #suffix -- Commented ** ntdomain -- Uncommented ** ldap -- Uncommented == Caveats == * Passwords need to be stored in plain text in the LDAP DB. You can limit in OpenLDAP who can do what with ACLs, and I did it in this case. I may write up about this later, but it isn't fully applicable here, as it's more of an OpenLDAP configuration then a FreeRADIUS configuration. ** As such, I highly recommend doing TLS on LDAP, since otherwise you might end up with passwords going over the wire in clear-text. * I know some of the stuff in LDAP isn't fully clear, or some of the more advanced stuff like VLAN assignment. I'll try to clear these up later, but for right now, this should get you up and going. == Resources used == * Sadly I set the majority of this up a long time ago, but I do seem to have some bookmarks, so I'll throw some of them here. Otherwise, I only used one recently from the FreeRADIUS mailing list. * http://vuksan.com/linux/dot1x/802-1x-LDAP.html -- Decent guide, also covers setting up OpenLDAP and it's ACLs, and device setup. * http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius * [http://wiki.freeradius.org/Home The FreeRADIUS Wiki] * http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg48720.html -- Email thread bookmarked. * http://lists.freeradius.org/pipermail/freeradius-users/2012-January/058185.html -- This thread, specially this post to get the Dynamic VLAN assignment working. == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. Sometimes I am in the #freeradius channel, sometimes not, but I am usually connected. ce0400c3a753a2278a10b4544a076b524c807f21 Setting up Cisco Switches for 802.1x Auth 0 8 37 2012-09-29T02:59:12Z Bpenglase 1 Initial Submit wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/20 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto dot1x violation-mode protect dot1x control-direction in dot1x reauthentication ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 ! </syntaxhighlight> 0bb69e8f7634101677eccc67564c2169df16f247 38 37 2012-09-29T03:22:23Z Bpenglase 1 /* The Code */ More Changes wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. c78754b7e4d9c84293c889cb499fcc25a7a292d8 39 38 2012-09-29T03:42:54Z Bpenglase 1 /* The Code */ wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> * Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. * Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything. * Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port. * Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC. * Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed). * Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate. * Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term. 35eeb0f8807bc2e2574be76b8a04d245d9edb215 40 39 2012-09-29T03:43:41Z Bpenglase 1 Added Resources and Fin wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> * Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. * Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything. * Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port. * Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC. * Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed). * Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate. * Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term. == Resources Used == * [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 Certification Guide] * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750) * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750) == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others. e62366ba055c69da6406829abeb4be395488e5de 41 40 2012-09-29T03:45:40Z Bpenglase 1 /* Resources Used */ wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> * Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. * Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything. * Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port. * Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC. * Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed). * Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate. * Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term. == Resources Used == * [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide] * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750) * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750) == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others. 3ba756223978e1e28b517b783753ab7978caa125 42 41 2012-09-29T03:46:35Z Bpenglase 1 /* The Code */ wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> * Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. * Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything. * Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port. * Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC. * Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed). * Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate. * Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term. == Resources Used == * [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide] * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750) * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750) == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others. ffeaa3251de52e55e6afb8d92864722d1eec45d3 43 42 2012-09-29T03:46:48Z Bpenglase 1 /* The Code */ wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> * Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. * Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything. * Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port. * Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC. * Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed). * Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate. * Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term. == Resources Used == * [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide] * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750) * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750) == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others. 45deaed94271ba66cc525abef3e9ff65f81b1b23 45 43 2012-09-29T03:57:32Z Bpenglase 1 wikitext text/x-wiki == Intro == There are many different guides out there on how to setup Cisco Switches to do 802.1x, or EAPoL. This is actually a part of the Cisco CCNP SWITCH exam. Generally, it's easy. Especially either reading the SWITCH Certification Guide, or reading over Cisco's website. The main thing I wanted to expand on while going through the SWITCH exam, was to expand 802.1x authentication into also assigning VLANs depending on what the RADIUS server returned for a specific user. When I read up on this, it was mostly "It just works(c)(tm)(r)", but it didn't for me. So, here's my documentation of how I got it to work. I'll dump the code in, then the things that need a bit more explaining, I'll explain below. == What does this page assume? == * You have basic Cisco IOS knowledge ** Have setup basic management connectivity (i.e. your switch can reach your RADIUS server) ** Have configured VLANs and 802.1q trunking * Have a RADIUS server to point to (I do have a guide on how to setup [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS+LDAP]] if you need to set one up) ** In my case, with LDAP, your user looks something like this: [[file:Ldap-radius.png]] * Have your wired clients setup and able to do EAPoL == My Testing Environment == * Several catalyst switch models ** 2950T-24 ** 2950G-48 ** 3550-24-PWR ** 3750-48-PS * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP|FreeRADIUS setup to refer to LDAP]], so thats how I'll be referring to accounts and what they contain. * Windows 7 * Mac OS X Mountain Lion == The Code == <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> aaa new-model ! ! aaa authentication dot1x default group radius aaa authorization network default group radius ! dot1x system-auth-control ! ! interface FastEthernet0/1 switchport access vlan 999 switchport mode access dot1x mac-auth-bypass dot1x pae authenticator dot1x port-control auto ! radius-server host 10.0.3.2 auth-port 1812 acct-port 1813 key testing1234 </syntaxhighlight> * Thats pretty much about it. === Things to note about the code === * Line 5: This is what enables the switch to change the VLAN to what is given by the RADIUS server. Without this, it just won't change the VLAN, and will put it in the access VLAN configured on the port, once authentication is successful. * Line 7: This actually enables 802.1x on the switch. One thing to note here is that 'port-control force-authorized' is the default on all ports. This way when you enable it, none of the ports go offline. * Line 11: You don't _have_ to configure an access VLAN here, but this is what it falls back to is RADIUS doesn't return anything. * Line 12: Before the 'dot1x' commands show up below, the port is required to be in access mode. You cannot have 802.1x on a trunking port. * Line 13: Not required, but allows machines on the network via the MAC address that do not have a 802.1x supplicant. The MAC just needs to be in your RADIUS server, with a password of the same MAC. * Line 14: Needed on newer switches. I found I didn't need it on the 2950's. This actually cause myself and another to not get 802.1x working on the 3750/2960 until I happened to come across it. This is not covered in the CCNP SWITCH Guide (although it is needed). * Line 15: This actually enables the authentication on the port. There are two other modes, but they aren't helpful to having the port authenticate. * Line 17: Radius server line, you can have multiple lines for different servers. Depending on the switch, the default ports could be in the 1600 range, so you may need to specify the port numbers here. The password goes after the 'key' term. == Resources Used == * [http://www.amazon.com/SWITCH-642-813-Official-Certification-Guide/dp/1587202433/ref=sr_1_1?ie=UTF8&qid=1348889727&sr=8-1&keywords=CCNP+Switch Cisco Official 642-813 (CCNP SWITCH) Certification Guide] * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1289244 - VLAN Assignment (3750) * http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_55_se/configuration/guide/sw8021x.html#wp1025133 - 802.1x Configuration (3750) == Fin == I am available on IRC if you have any questions or comments; irc.freenode.net, my Nickname is Sedorox. I am usually in the #cisco channel, as well as others. 1f427f334536690107f4bcdf9ece9dac7123cc8d File:Ldap-radius.png 6 9 44 2012-09-29T03:54:31Z Bpenglase 1 User configuration in LDAP that will put the user in VLAN 13 upon successful authentication. wikitext text/x-wiki User configuration in LDAP that will put the user in VLAN 13 upon successful authentication. 395f289516b499f5949438c10b0ad2a74fdf84d2 PXE Booting and Utilities Menu 0 10 47 2012-10-13T02:36:21Z Bpenglase 1 Initial commit, up to DHCP config wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "netboot/ipxe.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * This if statement breaks the "infinite loop" * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE. * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from 54a4af9d2c556a48a917b3a13e5b5e276b173a8a 48 47 2012-10-13T03:27:02Z Bpenglase 1 Post for the night, up to boot.php, and some commenting. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * This if statement breaks the "infinite loop" * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE. * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deploymeny Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on Freenode\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.com.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> * Woah!<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://10.0.3.2/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; //echo "set 66:ipv4 10.0.3.99\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function gparted() { echo ":gparted\n"; echo "kernel http://10.0.3.2/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://10.0.3.2/gparted/live/filesystem.squashfs\n"; echo "initrd http://10.0.3.2/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://10.0.3.2/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://10.0.3.2/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://10.0.3.2/memtest.0\n"; } function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } function vesamenu() { global $plembed; echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://10.0.3.2/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://10.0.3.2/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; //echo "imgargs tboot.b00 kernelopt=runweasel\n"; //echo "imgargs tboot.b00 ks=\${base-url}ks.cfg\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> * More continuing tomorrow... 1d48ce05428567cf3e6efaee5814da1153f6bf03 49 48 2012-10-13T03:30:56Z Bpenglase 1 /* dhcpd.conf */ Included link for chainloading/ breaking the loop wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deploymeny Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on Freenode\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.com.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> * Woah!<syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://10.0.3.2/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; //echo "set 66:ipv4 10.0.3.99\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function gparted() { echo ":gparted\n"; echo "kernel http://10.0.3.2/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://10.0.3.2/gparted/live/filesystem.squashfs\n"; echo "initrd http://10.0.3.2/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://10.0.3.2/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://10.0.3.2/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://10.0.3.2/memtest.0\n"; } function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } function vesamenu() { global $plembed; echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://10.0.3.2/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://10.0.3.2/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; //echo "imgargs tboot.b00 kernelopt=runweasel\n"; //echo "imgargs tboot.b00 ks=\${base-url}ks.cfg\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> * More continuing tomorrow... 5fb1fd0a176b5d4142ea4bc40e369025828062fb File:Ipxemenu1.png 6 11 50 2012-10-13T17:09:39Z Bpenglase 1 first screen of the iPXE menu wikitext text/x-wiki first screen of the iPXE menu 6532ec5eb0b2079c765349012a9602f4caf9e058 File:Ipxemenu2.png 6 12 51 2012-10-13T17:10:21Z Bpenglase 1 Second page of the iPXE menu wikitext text/x-wiki Second page of the iPXE menu e0b24a5334eccdfd902a36f83a368fb45f388895 52 51 2012-10-13T17:12:50Z Bpenglase 1 Bpenglase uploaded a new version of &quot;[[File:Ipxemenu2.png]]&quot;: second page of the iPXE menu, with corrected wording. wikitext text/x-wiki Second page of the iPXE menu e0b24a5334eccdfd902a36f83a368fb45f388895 53 52 2012-10-13T17:14:14Z Bpenglase 1 Bpenglase uploaded a new version of &quot;[[File:Ipxemenu2.png]]&quot;: Yet another upload, with corrected spelling. wikitext text/x-wiki Second page of the iPXE menu e0b24a5334eccdfd902a36f83a368fb45f388895 66 53 2012-10-14T19:34:01Z Bpenglase 1 Bpenglase uploaded a new version of &quot;[[File:Ipxemenu2.png]]&quot;: Updated to reflect new windows7 installer. wikitext text/x-wiki Second page of the iPXE menu e0b24a5334eccdfd902a36f83a368fb45f388895 PXE Booting and Utilities Menu 0 10 54 49 2012-10-13T17:59:54Z Bpenglase 1 Submit so I don't have to keep reformatting the thing when it screws up! Ugh.... wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="89"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> fccac010be3d8c47006ce8b05111d39571abdaf0 55 54 2012-10-13T18:05:46Z Bpenglase 1 Corrected numbering. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> -- * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> -- * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> bdbb7eb15a7910b1d12290184c5338aaef3df7c6 56 55 2012-10-13T18:15:42Z Bpenglase 1 Finished comments on boot.php, and added isolinux.cfg for esxi wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/ipxe.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> -- * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> -- * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> -- * This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg (esxi) === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> 459d0c36fbc55c8df76a12f8a0c0cd9f65b63e62 57 56 2012-10-13T18:42:15Z Bpenglase 1 Added FIN section, and resources wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> -- * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> -- * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> -- * This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * [http://ipxe.org] -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * [http://lists.ipxe.org/pipermail/ipxe-devel/] -- iPXE Mailing List * [http://etherboot.org] -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * [http://www.networksorcery.com/enp/protocol/bootp/options.htm] -- General DHCP Options * [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/] -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * [https://gist.github.com/2234639] -- Robin Smidsrød's iPXE menu * [http://www.youtube.com/watch?v=GofOqhO6VVM] -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 9f157aa3da6e697be4b53f8a73748bfe5fd0ac80 58 57 2012-10-13T18:44:25Z Bpenglase 1 removed brackets from the URLs wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> -- * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> -- * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> -- * This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 112305ea078989610537d8aea7643a5467098082 59 58 2012-10-13T18:52:34Z Bpenglase 1 /* dhcpd.conf */ added link to iPXE DHCP Options wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/ipxe.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> -- * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> -- * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> -- * This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 6548fc355f61ddfff41eb5f0039233d250013057 60 59 2012-10-13T18:55:22Z Bpenglase 1 /* ipxe.kkpxe */ updated filename. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php $mac = ""; $servername = $_SERVER['SERVER_NAME']; if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } header ( "Content-type: text/plain" ); </syntaxhighlight> -- * The above sets some variables, and grabs them from the URL, if they are set, and sets the content-type. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> if ( $mac != "" ) { switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel http://boot.example.com/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel http://boot.example.com/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd http://boot.example.com/fe1-initrd.img\n"; break; default: ipxemenu(); break; } echo "boot"; } else { exit(); } </syntaxhighlight> -- * This is where the fun begins! * First, it makes sure a MAC address is set, otherwise it just exits to an empty file * Then it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> -- * This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 85909232319c1268c5e54661fef490f184d73475 61 60 2012-10-14T19:09:33Z Bpenglase 1 /* boot.php */ Updating, but submitting so the formatting doesn't go off again... wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="8"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; }</syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="37"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="90"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.107::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { echo ":esxi5sl\n"; echo "set 210:string http://boot.example.com/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain http://boot.example.com/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="103"> function qwipe() { echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe http://boot.example.com/wipe2.img\n"; echo "goto menustart\n"; } function b57() { echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe http://boot.example.com/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set net0/next-server 10.0.3.99\n"; echo "chain tftp://10.0.3.99/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="132"> function gparted() { echo ":gparted\n"; echo "kernel http://boot.example.com/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=http://boot.example.com/gparted/live/filesystem.squashfs\n"; echo "initrd http://boot.example.com/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 http://boot.example.com/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe http://boot.example.com/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { echo ":dft\n"; echo "sanboot --drive 0x00 http://boot.example.com/dft32_v416_b00_install.IMG\n"; } function memtest() { echo ":memtest\n"; echo "chain http://boot.example.com/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="170"> function sanbootpe() { echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 http://boot.example.com/PEBoot-07_08_11.iso\n"; } function wimbootpe() { echo ":wimboot\n"; echo "kernel wimboot\n"; echo "initrd winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd winpe/Boot/BCD BCD\n"; echo "initrd winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd winpe/Boot/boot.wim boot.wim\n"; echo "imgstat\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { echo ":vesamenu\n"; echo "set 210:string http://boot.example.com/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { echo ":esxi5\n"; echo "chain http://boot.example.com/esxi51/esxi51.ipxe\n"; echo "echo failing back\n"; echo "goto end\n"; echo "set base-url http://boot.example.com/esxi5/\n"; echo "kernel \${base-url}tboot runweasel\n"; echo "module \${base-url}b.b00\n"; echo "module \${base-url}useropts.gz\n"; echo "module \${base-url}k.b00\n"; echo "module \${base-url}a.b00\n"; echo "module \${base-url}ata-pata.v00\n"; echo "module \${base-url}ata-pata.v01\n"; echo "module \${base-url}ata-pata.v02\n"; echo "module \${base-url}ata-pata.v03\n"; echo "module \${base-url}ata-pata.v04\n"; echo "module \${base-url}ata-pata.v05\n"; echo "module \${base-url}ata-pata.v06\n"; echo "module \${base-url}ata-pata.v07\n"; echo "module \${base-url}block-cc.v00\n"; echo "module \${base-url}ehci-ehc.v00\n"; echo "module \${base-url}s.v00\n"; echo "module \${base-url}weaselin.i00\n"; echo "module \${base-url}ima-qla4.v00\n"; echo "module \${base-url}ipmi-ipm.v00\n"; echo "module \${base-url}ipmi-ipm.v01\n"; echo "module \${base-url}ipmi-ipm.v02\n"; echo "module \${base-url}misc-cni.v00\n"; echo "module \${base-url}misc-dri.v00\n"; echo "module \${base-url}net-be2n.v00\n"; echo "module \${base-url}net-bnx2.v00\n"; echo "module \${base-url}net-bnx2.v01\n"; echo "module \${base-url}net-cnic.v00\n"; echo "module \${base-url}net-e100.v00\n"; echo "module \${base-url}net-e100.v01\n"; echo "module \${base-url}net-enic.v00\n"; echo "module \${base-url}net-forc.v00\n"; echo "module \${base-url}net-igb.v00\n"; echo "module \${base-url}net-ixgb.v00\n"; echo "module \${base-url}net-nx-n.v00\n"; echo "module \${base-url}net-r816.v00\n"; echo "module \${base-url}net-r816.v01\n"; echo "module \${base-url}net-s2io.v00\n"; echo "module \${base-url}net-sky2.v00\n"; echo "module \${base-url}net-tg3.v00\n"; echo "module \${base-url}ohci-usb.v00\n"; echo "module \${base-url}sata-ahc.v00\n"; echo "module \${base-url}sata-ata.v00\n"; echo "module \${base-url}sata-sat.v00\n"; echo "module \${base-url}sata-sat.v01\n"; echo "module \${base-url}sata-sat.v02\n"; echo "module \${base-url}sata-sat.v03\n"; echo "module \${base-url}scsi-aac.v00\n"; echo "module \${base-url}scsi-adp.v00\n"; echo "module \${base-url}scsi-aic.v00\n"; echo "module \${base-url}scsi-bnx.v00\n"; echo "module \${base-url}scsi-fni.v00\n"; echo "module \${base-url}scsi-hps.v00\n"; echo "module \${base-url}scsi-ips.v00\n"; echo "module \${base-url}scsi-lpf.v00\n"; echo "module \${base-url}scsi-meg.v00\n"; echo "module \${base-url}scsi-meg.v01\n"; echo "module \${base-url}scsi-meg.v02\n"; echo "module \${base-url}scsi-mpt.v00\n"; echo "module \${base-url}scsi-mpt.v01\n"; echo "module \${base-url}scsi-mpt.v02\n"; echo "module \${base-url}scsi-qla.v00\n"; echo "module \${base-url}scsi-qla.v01\n"; echo "module \${base-url}scsi-rst.v00\n"; echo "module \${base-url}uhci-usb.v00\n"; echo "module \${base-url}tools.t00\n"; echo "module \${base-url}imgdb.tgz\n"; echo "module \${base-url}imgpayld.tgz\n"; echo "imgstat\n"; echo "boot\n"; } ?> </syntaxhighlight> -- * This tries to load a esxi51.ipxe file first, which is basically the rest of whats here, but just another place I was playing around with. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. c2f4bd3b1735ee998b02d819352df2794993a54d 62 61 2012-10-14T19:24:17Z Bpenglase 1 /* boot.php */ Finished updating. Need to update line numbers. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; } </syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function win7pro64() { global $servername,$serverproto; echo ":win7pro64\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/BCD BCD\n"; echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { global $servername,$serverproto; echo ":esxi5sl\n"; echo "set 210:string $serverproto$servername/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain $serverproto$servername/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131"> function qwipe() { global $servername,$serverproto; echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n"; echo "goto menustart\n"; } function b57() { global $servername,$serverproto; echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { global $servername,$serverproto; echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set wdsserver:ipv4 10.0.3.99\n"; echo "set net0/next-server \${wdsserver}\n"; echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164"> function gparted() { global $servername,$serverproto; echo ":gparted\n"; echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n"; echo "initrd $serverproto$servername/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { global $servername,$serverproto; echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { global $servername,$serverproto; echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { global $servername,$serverproto; echo ":dft\n"; echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n"; } function memtest() { global $servername,$serverproto; echo ":memtest\n"; echo "chain $serverproto$servername/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="206"> function sanbootpe() { global $servername,$serverproto; echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n"; } function wimbootpe() { global $servername,$serverproto; echo ":wimboot\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="185"> function vesamenu() { global $servername,$serverproto; echo ":vesamenu\n"; echo "set 210:string $serverproto$servername/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { global $servername,$serverproto; echo ":esxi5\n"; echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n"; echo "goto end\n"; } ?> </syntaxhighlight> -- * Chains to an ipxe config in the esxi51 directory, to load the ESXi installer. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 7a04ed519a1a544b3a9c746cd53f739bec0e57ad 63 62 2012-10-14T19:25:33Z Bpenglase 1 /* boot.php */ Updated line numbers. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; } </syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function win7pro64() { global $servername,$serverproto; echo ":win7pro64\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/BCD BCD\n"; echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { global $servername,$serverproto; echo ":esxi5sl\n"; echo "set 210:string $serverproto$servername/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain $serverproto$servername/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131"> function qwipe() { global $servername,$serverproto; echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n"; echo "goto menustart\n"; } function b57() { global $servername,$serverproto; echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { global $servername,$serverproto; echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set wdsserver:ipv4 10.0.3.99\n"; echo "set net0/next-server \${wdsserver}\n"; echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164"> function gparted() { global $servername,$serverproto; echo ":gparted\n"; echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n"; echo "initrd $serverproto$servername/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { global $servername,$serverproto; echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { global $servername,$serverproto; echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { global $servername,$serverproto; echo ":dft\n"; echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n"; } function memtest() { global $servername,$serverproto; echo ":memtest\n"; echo "chain $serverproto$servername/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207"> function sanbootpe() { global $servername,$serverproto; echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n"; } function wimbootpe() { global $servername,$serverproto; echo ":wimboot\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="221"> function vesamenu() { global $servername,$serverproto; echo ":vesamenu\n"; echo "set 210:string $serverproto$servername/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { global $servername,$serverproto; echo ":esxi5\n"; echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n"; echo "goto end\n"; } ?> </syntaxhighlight> -- * Chains to an ipxe config in the esxi51 directory, to load the ESXi installer. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. f681f790818b732aba04b9cc54e3a0da5d6367d4 64 63 2012-10-14T19:26:18Z Bpenglase 1 /* boot.php */ Updated line numbers. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; } </syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function win7pro64() { global $servername,$serverproto; echo ":win7pro64\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/BCD BCD\n"; echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { global $servername,$serverproto; echo ":esxi5sl\n"; echo "set 210:string $serverproto$servername/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain $serverproto$servername/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131"> function qwipe() { global $servername,$serverproto; echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n"; echo "goto menustart\n"; } function b57() { global $servername,$serverproto; echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { global $servername,$serverproto; echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set wdsserver:ipv4 10.0.3.99\n"; echo "set net0/next-server \${wdsserver}\n"; echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164"> function gparted() { global $servername,$serverproto; echo ":gparted\n"; echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n"; echo "initrd $serverproto$servername/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { global $servername,$serverproto; echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { global $servername,$serverproto; echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { global $servername,$serverproto; echo ":dft\n"; echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n"; } function memtest() { global $servername,$serverproto; echo ":memtest\n"; echo "chain $serverproto$servername/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207"> function sanbootpe() { global $servername,$serverproto; echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n"; } function wimbootpe() { global $servername,$serverproto; echo ":wimboot\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223"> function vesamenu() { global $servername,$serverproto; echo ":vesamenu\n"; echo "set 210:string $serverproto$servername/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { global $servername,$serverproto; echo ":esxi5\n"; echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n"; echo "goto end\n"; } ?> </syntaxhighlight> -- * Chains to an ipxe config in the esxi51 directory, to load the ESXi installer. * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 6ed362f715f522a6c480360530682f10e1d29f92 65 64 2012-10-14T19:31:29Z Bpenglase 1 /* Files */ Adds native iPXE loading of esxi5.1 wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "undionly.kkpxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.kkpxe === * This file is built from the iPXE source, running "make bin/undionly.kkpxe", then copying the bin/undionly.kkpxe file to your TFTP server's root directory === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; } </syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function win7pro64() { global $servername,$serverproto; echo ":win7pro64\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/BCD BCD\n"; echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { global $servername,$serverproto; echo ":esxi5sl\n"; echo "set 210:string $serverproto$servername/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain $serverproto$servername/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131"> function qwipe() { global $servername,$serverproto; echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n"; echo "goto menustart\n"; } function b57() { global $servername,$serverproto; echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { global $servername,$serverproto; echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set wdsserver:ipv4 10.0.3.99\n"; echo "set net0/next-server \${wdsserver}\n"; echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164"> function gparted() { global $servername,$serverproto; echo ":gparted\n"; echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n"; echo "initrd $serverproto$servername/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { global $servername,$serverproto; echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { global $servername,$serverproto; echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { global $servername,$serverproto; echo ":dft\n"; echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n"; } function memtest() { global $servername,$serverproto; echo ":memtest\n"; echo "chain $serverproto$servername/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207"> function sanbootpe() { global $servername,$serverproto; echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n"; } function wimbootpe() { global $servername,$serverproto; echo ":wimboot\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223"> function vesamenu() { global $servername,$serverproto; echo ":vesamenu\n"; echo "set 210:string $serverproto$servername/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { global $servername,$serverproto; echo ":esxi5\n"; echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n"; echo "goto end\n"; } ?> </syntaxhighlight> -- * Chains to an ipxe config in the esxi51 directory, to load the ESXi installer. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> === esxi51.ipxe === <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> #!ipxe imgfree kernel tboot runweasel module b.b00 module k.b00 module chardevs module a.b00 module user.b00 module s.v00 module ata_pata.v00 module ata_pata.v01 module ata_pata.v02 module ata_pata.v03 module ata_pata.v04 module ata_pata.v05 module ata_pata.v06 module ata_pata.v07 module block_cc.v00 module ehci_ehc.v00 module weaselin.t00 module esx_dvfi.v00 module xlibs.v00 module ima_qla4.v00 module ipmi_ipm.v00 module ipmi_ipm.v01 module ipmi_ipm.v02 module misc_cni.v00 module misc_dri.v00 module net_be2n.v00 module net_bnx2.v00 module net_bnx2.v01 module net_cnic.v00 module net_e100.v00 module net_e100.v01 module net_enic.v00 module net_forc.v00 module net_igb.v00 module net_ixgb.v00 module net_nx_n.v00 module net_r816.v00 module net_r816.v01 module net_s2io.v00 module net_sky2.v00 module net_tg3.v00 module net_vmxn.v00 module ohci_usb.v00 module sata_ahc.v00 module sata_ata.v00 module sata_sat.v00 module sata_sat.v01 module sata_sat.v02 module sata_sat.v03 module sata_sat.v04 module scsi_aac.v00 module scsi_adp.v00 module scsi_aic.v00 module scsi_bnx.v00 module scsi_fni.v00 module scsi_hps.v00 module scsi_ips.v00 module scsi_lpf.v00 module scsi_meg.v00 module scsi_meg.v01 module scsi_meg.v02 module scsi_mpt.v00 module scsi_mpt.v01 module scsi_mpt.v02 module scsi_qla.v00 module scsi_qla.v01 module scsi_rst.v00 module uhci_usb.v00 module tools.t00 module xorg.v00 module imgdb.tgz module imgpayld.tgz boot </syntaxhighlight> * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 76863403e43005a73ac73b8e7d361df7f399c3dd 67 65 2012-10-14T20:08:55Z Bpenglase 1 /* Files */ Edited ipxe file that loads. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.pxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.pxe === * This file is built from the iPXE source, running "make bin/ipxe.pxe", then copying the bin/ipxe.pxe file to your TFTP server's root directory * More information on the extensions can be found [http://etherboot.org/wiki/gpxe_imagetypes here on the Etherboot website] * As stated in the website linked above, pxe unloads the stack, which then means ipxe relies on it's own drivers for the network card. If you to keep the driver loaded, you may want to consider using .kpxe or .kkpxe === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; } </syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function win7pro64() { global $servername,$serverproto; echo ":win7pro64\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/BCD BCD\n"; echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { global $servername,$serverproto; echo ":esxi5sl\n"; echo "set 210:string $serverproto$servername/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain $serverproto$servername/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131"> function qwipe() { global $servername,$serverproto; echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n"; echo "goto menustart\n"; } function b57() { global $servername,$serverproto; echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { global $servername,$serverproto; echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set wdsserver:ipv4 10.0.3.99\n"; echo "set net0/next-server \${wdsserver}\n"; echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164"> function gparted() { global $servername,$serverproto; echo ":gparted\n"; echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n"; echo "initrd $serverproto$servername/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { global $servername,$serverproto; echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { global $servername,$serverproto; echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { global $servername,$serverproto; echo ":dft\n"; echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n"; } function memtest() { global $servername,$serverproto; echo ":memtest\n"; echo "chain $serverproto$servername/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207"> function sanbootpe() { global $servername,$serverproto; echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n"; } function wimbootpe() { global $servername,$serverproto; echo ":wimboot\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223"> function vesamenu() { global $servername,$serverproto; echo ":vesamenu\n"; echo "set 210:string $serverproto$servername/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { global $servername,$serverproto; echo ":esxi5\n"; echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n"; echo "goto end\n"; } ?> </syntaxhighlight> -- * Chains to an ipxe config in the esxi51 directory, to load the ESXi installer. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> === esxi51.ipxe === <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> #!ipxe imgfree kernel tboot runweasel module b.b00 module k.b00 module chardevs module a.b00 module user.b00 module s.v00 module ata_pata.v00 module ata_pata.v01 module ata_pata.v02 module ata_pata.v03 module ata_pata.v04 module ata_pata.v05 module ata_pata.v06 module ata_pata.v07 module block_cc.v00 module ehci_ehc.v00 module weaselin.t00 module esx_dvfi.v00 module xlibs.v00 module ima_qla4.v00 module ipmi_ipm.v00 module ipmi_ipm.v01 module ipmi_ipm.v02 module misc_cni.v00 module misc_dri.v00 module net_be2n.v00 module net_bnx2.v00 module net_bnx2.v01 module net_cnic.v00 module net_e100.v00 module net_e100.v01 module net_enic.v00 module net_forc.v00 module net_igb.v00 module net_ixgb.v00 module net_nx_n.v00 module net_r816.v00 module net_r816.v01 module net_s2io.v00 module net_sky2.v00 module net_tg3.v00 module net_vmxn.v00 module ohci_usb.v00 module sata_ahc.v00 module sata_ata.v00 module sata_sat.v00 module sata_sat.v01 module sata_sat.v02 module sata_sat.v03 module sata_sat.v04 module scsi_aac.v00 module scsi_adp.v00 module scsi_aic.v00 module scsi_bnx.v00 module scsi_fni.v00 module scsi_hps.v00 module scsi_ips.v00 module scsi_lpf.v00 module scsi_meg.v00 module scsi_meg.v01 module scsi_meg.v02 module scsi_mpt.v00 module scsi_mpt.v01 module scsi_mpt.v02 module scsi_qla.v00 module scsi_qla.v01 module scsi_rst.v00 module uhci_usb.v00 module tools.t00 module xorg.v00 module imgdb.tgz module imgpayld.tgz boot </syntaxhighlight> * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. a749cf4fb6829b98b0f96c1693c54fc529b17f1b 68 67 2012-10-14T20:11:07Z Bpenglase 1 /* Resources Used */ added forum link wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my home network. My work one, I'll put in another entry (as it's significantly different in it's programming, but does the same functions), and link here. Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My home network consists of [http://ipxe.org iPXE], PHP scripting, and separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of PHP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Linux, Distro: Gentoo (~AMD64 "Unstable") * Apache 2.4.3 * PHP 5.4.7 * tftp-hpa 5.2 * iPXE (current GIT master) * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === dhcpd.conf === * This information can be placed globally, specific subnets, or individual filename/next-server can be placed on host definitions * Relevant sections of my ISC DHCP config: <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> if exists user-class { if option user-class = "iPXE" { filename "http://boot.example.com/preboot.php"; } } else { filename "ipxe.pxe"; } next-server 10.0.3.2; </syntaxhighlight> * [http://ipxe.org/howto/chainloading This if statement breaks the "infinite loop"] * The filename listed on line 3 is for when iPXE does the DHCP request * The filename listed on line 6 is for when a non-iPXE client does a DHCP request, to get it to use iPXE * The next-server on line 8 is the TFTP server that the non-iPXE clients will grab the above file from * You can also use some [http://ipxe.org/howto/dhcpd#ipxe-specific_options iPXE specific DHCP options] to gain more control over iPXE === ipxe.pxe === * This file is built from the iPXE source, running "make bin/ipxe.pxe", then copying the bin/ipxe.pxe file to your TFTP server's root directory * More information on the extensions can be found [http://etherboot.org/wiki/gpxe_imagetypes here on the Etherboot website] * As stated in the website linked above, pxe unloads the stack, which then means ipxe relies on it's own drivers for the network card. If you to keep the driver loaded, you may want to consider using .kpxe or .kkpxe === 01_boot_vhost.conf === * This is placed in /etc/apache2/vhosts.d, to configure the boot.example.com vhost * This configures your virtual host (boot.example.com from above), to point to where you want to store your files. I choose to keep mine in the TFTP root, under the "netboot" folder, so everything related to the netboot is contained in that folder. <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> <VirtualHost boot.example.com:80> ServerName boot.example.com DocumentRoot "/tftp/netboot/" <Directory "/tftp/netboot"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost> </syntaxhighlight> === preboot.php === * This is the file that the iPXE client first grabs to see what it needs to do <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php echo "#!ipxe\n"; echo "chain http://".$_SERVER['SERVER_NAME']."/boot.php?MAC=\${netX/mac}"; ?> </syntaxhighlight> * So this is an extremely simple file, as you can tell. It's purpose is to pass the MAC address of the booting network card off to the boot.php script. So this references the same server name (pulls it in from the PHP variables), and then uses the ${netX/mac} iPXE variable to pull the MAC of the active network card, via GET (Variables in the URL). === boot.php === * This is the big guy, so I'm going to do some inline comments to explain it <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS"> <?php // First, check the MAC, if not present, exit; no use continuing as we can assume the netboot isn't correct if (isset($_GET['MAC'])) { $mac = $_GET['MAC']; } else { exit(); } header ( "Content-type: text/plain" ); // Figure out which protocol we're using if (isset($_SERVER['HTTPS'])) { $serverproto = "https://"; } else { $serverproto = "http://"; } // If we're running a non-standard port, include it. Otherwise, assume defaults. if ( ($_SERVER['SERVER_PORT'] != "80") && ($_SERVER['SERVER_PORT'] != "443")) { $servername = "$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]"; } else { $servername = $_SERVER['SERVER_NAME']; } </syntaxhighlight> -- * The above has some inline comments that should explain most of it. In my case, if there is no MAC, just quit, as it didn't run through preboot.php first, therefore is not correct * The rest of it is used to make the script portable. This allows you to use http/https, and also run on non-standard ports, and it can change at runtime. Perfect example of this is internal versus external booting, in reference to say your home network -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="24"> switch ($mac) { case "00:0c:29:xx:xx:xx": case "00:e0:b8:xx:xx:xx": // Testing VM ipxemenu(); break; case "bc:ae:c5:xx:xx:xx": echo "#!ipxe\n"; // Atom - Living Room Frontend echo "kernel $serverproto$servername/bzImage-Atom ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe,nfsvers=3,tcp,hard,intr,nolock vga=0x317 quiet\n"; // splash=silent,theme:MythTV quiet console=tty1\n"; // echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; case "00:10:18:xx:xx:xx": echo "#!ipxe\n"; // Athlon 64 HDFE - Bedroom Frontend echo "kernel $serverproto$servername/bzImage-A64 ip=dhcp root=/dev/nfs nfsroot=10.0.3.2:/nfsroot/hdfe1,nfsvers=3,tcp,hard,intr,nolock vga=0x317\n"; //splash=silent,theme:MythTV quiet console=tty1\n"; //echo "initrd $serverproto$servername/fe1-initrd.img\n"; break; default: ipxemenu(); break; } </syntaxhighlight> -- * This is where the fun begins! * First, it searches to see if there are special per-MAC instructions to do. In the above example, the first two MACs run the ipxemenu() function, that I was using for testing, from when I was switching away from a vesamenu * The next two are two different MythTV Frontends I have in our apartment. These netboot to a NFSRoot, so you can see how to have iPXE directly load Linux over HTTP * Then if all else fails (usual), run the ipxemenu() function to present the iPXE menu. (Here I use to have stuff to chain to pxelinux.0, and load a vesamenu up, but I recently switched to iPXE's menu. For pxelinux integration, see my work menu) -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="48"> function ipxemenu() { echo "#!ipxe\n"; echo ":menustart\n"; echo "menu iPXE Boot Menu\n"; echo "item --gap -- Diagnostics\n"; echo "item memtest Memtest86+\n"; echo "item dft Drive Fitness Test\n"; echo "item spinrite Spinrite\n"; echo "item hdt Hardware Detection Tool\n"; echo "item b57 b57 Diags\n"; echo "item qwipe Quick Wipe\n"; echo "item --gap -- Internet Boots\n"; echo "item ipxedemo iPXE Demo Boot\n"; echo "item ritboot rit.edu clone of boot.kernel.org\n"; echo "item --gap -- Live Systems\n"; echo "item gparted GParted\n"; echo "item smartos SmartOS\n"; echo "item --gap -- WinPE\n"; echo "item peboot Windows PEBoot via SANBoot\n"; echo "item wimboot Windows PEBoot via WIMBoot\n"; echo "item --gap -- Installers\n"; echo "item esxi5 ESXi 5.1 Installer\n"; echo "item esxi5sl ESXi 5.0 Installer via PXELinux\n"; echo "item freedos FreeDOS 1.1\n"; echo "item vesamenu Vesamenu\n"; echo "item win7pro64 Windows 7 Professional AMD64 Install\n"; echo "item --gap -- Other PXE Systems\n"; echo "item wds Windows Deployment Services\n"; echo "item shell iPXE Shell\n"; echo "item sanhook Sanhook test on FreeNAS\n"; echo "choose os && goto \${os}\n"; echo ":shell\n"; echo "shell\n"; win7pro64(); esxi5sl(); sanhook(); qwipe(); b57(); freedos(); smartos(); gparted(); wds(); hdt(); memtest(); ipxedemo(); ritboot(); dft(); spinrite(); sanbootpe(); wimbootpe(); vesamenu(); esxi5(); echo ":end\n"; } </syntaxhighlight> -- * This is the function that creates the main [http://ipxe.org/cmd/menu iPXE menu] * You can check the full syntax from the link above, but it's fairly simple * This creates the menu that is seen when the client is booted. It looks something like this: [[file:ipxemenu1.png]] [[file:ipxemenu2.png]] * Once the menu is created, it calls the different functions to include the goto markers, otherwise the menu will fail is that option is selected. I choose to do it this way, with the intention of eventually adding options where the menu can be dynamic depending on the machine * I also added a :end goto marker, at the end, as I found pxelinux needed this to boot, otherwise it continued on through this menu (i.e. booting the option that was placed after it) * Most of the below, you can find really good documentation on the iPXE website. However, I will note anything special as needed -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="102"> function win7pro64() { global $servername,$serverproto; echo ":win7pro64\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/win7instadk/bootmgr bootmgr\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segmono_boot.ttf segmono_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/segoe_slboot.ttf segoe_slboot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/kor_boot.ttf kor_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/Fonts/wgl4_boot.ttf wgl4_boot.ttf\n"; echo "initrd $serverproto$servername/win7instadk/BCD BCD\n"; echo "initrd $serverproto$servername/win7instadk/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/win7instadk/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * This uses [http://ipxe.org/wimboot wimboot] to boot the WIM file for Windows PE Environments. This particular one was created with the Windows ADK (WinPE 4.0), and has a script to mount a SMB Share that contains the Windows 7 installer. This will be detailed in another entry, and linked here at that time -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="117"> function sanhook() { echo ":sanhook\n"; echo "sanhook iscsi:10.0.3.101::::iqn.2011-03.example.org.istgt:test\n"; echo "sleep 5\n"; echo "goto menustart\n"; } function esxi5sl() { global $servername,$serverproto; echo ":esxi5sl\n"; echo "set 210:string $serverproto$servername/esxi5/\n"; echo "set 209:string isolinux.cfg\n"; echo "chain $serverproto$servername/pxelinux.0\n"; echo "goto end\n"; } </syntaxhighlight> -- * This boots the ESXi installer via Syslinux (pxelinux/mboot). I found this way currently works. * This will be documented as other files, below. -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="131"> function qwipe() { global $servername,$serverproto; echo ":qwipe\n"; echo "sanboot --drive 0x00 --no-describe $serverproto$servername/wipe2.img\n"; echo "goto menustart\n"; } function b57() { global $servername,$serverproto; echo ":b57\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/B57udiag-15.23.iso\n"; echo "goto menustart\n"; } function freedos() { global $servername,$serverproto; echo ":freedos\n"; echo "sanboot --drive 0xa0 --no-describe $serverproto$servername/fd11src.iso\n"; echo "goto menustart\n"; } function smartos() { echo ":smartos\n"; echo "kernel smartos/platform/i86pc/kernel/amd64/unix -B console=text,standalone=true,noimport=true,root_shadow='\$5\$2HOHRnK3\$NvLlm.1KQBbB0WjoP7xcIwGnllhzp2HnT.mDO7DpxYA'\n"; echo "module smartos/platform/i86pc/amd64/boot_archive\n"; echo "boot\n"; echo "sleep 10\n"; } function wds() { echo ":wds\n"; echo "set wdsserver:ipv4 10.0.3.99\n"; echo "set net0/next-server \${wdsserver}\n"; echo "chain tftp://\${wdsserver}/boot%5Cx86%5cwdsnbp.com\n"; echo "sleep 10\n"; echo "goto menustart\n"; } </syntaxhighlight> -- * This one a lot of people may be interested in. This will chain to a Windows Deployment Services. * Things to note here, the wdsnbp.com looks at the next-server in the dhcp packets for where to talk to, well, this may not actually be your windows server, it is not in my case. This sets the next-server to the WDS Server, then chains to it, so that it boots properly. * Also note the hex in the tftp URL. This is needed, as it's a Windows TFTP Server, so it's actually in the path of boot\x86\wdsnbp.com * TODO? Use iPXE arch detection to boot 64bit? -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="164"> function gparted() { global $servername,$serverproto; echo ":gparted\n"; echo "kernel $serverproto$servername/gparted/live/vmlinuz boot=live config union=aufs noswap noprompt fetch=$serverproto$servername/gparted/live/filesystem.squashfs\n"; echo "initrd $serverproto$servername/gparted/live/initrd.img\n"; echo "boot\n"; echo "sleep 10\n"; echo "goto menustart\n"; } function hdt() { global $servername,$serverproto; echo ":hdt\n"; echo "sanboot --no-describe --drive 0x00 $serverproto$servername/hdt-0.5.0.img\n"; echo "goto menustart\n"; } function spinrite() { global $servername,$serverproto; echo ":spinrite\n"; echo "sanboot --drive 0xa1 --no-describe $serverproto$servername/spinrite.iso\n"; echo "goto menustart\n"; } function ipxedemo() { echo ":ipxedemo\n"; echo "chain http://boot.ipxe.org/demo/boot.php\n"; } function ritboot() { echo ":ritboot\n"; echo "set 209:string pxelinux.cfg/default\n"; echo "set 210:string http://boot.rit.edu/bko/\n"; echo "chain http://boot.rit.edu/bko/pxelinux.0\n"; echo "goto :menustart\n"; } function dft() { global $servername,$serverproto; echo ":dft\n"; echo "sanboot --drive 0x00 $serverproto$servername/dft32_v416_b00_install.IMG\n"; } function memtest() { global $servername,$serverproto; echo ":memtest\n"; echo "chain $serverproto$servername/memtest.0\n"; } </syntaxhighlight> -- * This is the [http://lists.ipxe.org/pipermail/ipxe-devel/2012-July/001562.html memtest.0 NBP from iPXE] ([http://forum.canardpc.com/threads/69874-PATCH-memtest86-as-a-PXE-NBP patches were submitted to memtest], but I don't think they included them yet). -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="207"> function sanbootpe() { global $servername,$serverproto; echo ":peboot\n"; echo "set keep-san 1\n"; echo "sanboot --drive 0x81 $serverproto$servername/PEBoot-07_08_11.iso\n"; } function wimbootpe() { global $servername,$serverproto; echo ":wimboot\n"; echo "kernel $serverproto$servername/wimboot\n"; echo "initrd $serverproto$servername/winpe/Boot/bootmgr.exe bootmgr.exe\n"; echo "initrd $serverproto$servername/winpe/Boot/BCD BCD\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.sdi boot.sdi\n"; echo "initrd $serverproto$servername/winpe/Boot/boot.wim boot.wim\n"; echo "boot\n"; } </syntaxhighlight> -- * [http://ipxe.org/howto/winpe wimboot] is a much better way of booting WinPE via iPXE. It's extremely quick, and saves memory! -- <syntaxhighlight lang="php" line="GESHI_NORMAL_LINE_NUMBERS" line start="223"> function vesamenu() { global $servername,$serverproto; echo ":vesamenu\n"; echo "set 210:string $serverproto$servername/\n"; echo "set 209:string mainmenu.gpxe\n"; echo "chain \${210:string}pxelinux.0\n"; } function esxi5() { global $servername,$serverproto; echo ":esxi5\n"; echo "chain $serverproto$servername/esxi51/esxi51.ipxe\n"; echo "goto end\n"; } ?> </syntaxhighlight> -- * Chains to an ipxe config in the esxi51 directory, to load the ESXi installer. -- === isolinux.cfg === * I made a quick and simple file that loads the installer immediately, instead of hitting the default boot menu * In addition to the above, [http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ you also need to make some other modifications] (that link also contains the other part of the instructions to get it all setup -- basic instructions to get the installer to PXE boot) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> DEFAULT install LABEL install KERNEL mboot.c32 APPEND -c boot.cfg </syntaxhighlight> === esxi51.ipxe === <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> #!ipxe imgfree kernel tboot runweasel module b.b00 module k.b00 module chardevs module a.b00 module user.b00 module s.v00 module ata_pata.v00 module ata_pata.v01 module ata_pata.v02 module ata_pata.v03 module ata_pata.v04 module ata_pata.v05 module ata_pata.v06 module ata_pata.v07 module block_cc.v00 module ehci_ehc.v00 module weaselin.t00 module esx_dvfi.v00 module xlibs.v00 module ima_qla4.v00 module ipmi_ipm.v00 module ipmi_ipm.v01 module ipmi_ipm.v02 module misc_cni.v00 module misc_dri.v00 module net_be2n.v00 module net_bnx2.v00 module net_bnx2.v01 module net_cnic.v00 module net_e100.v00 module net_e100.v01 module net_enic.v00 module net_forc.v00 module net_igb.v00 module net_ixgb.v00 module net_nx_n.v00 module net_r816.v00 module net_r816.v01 module net_s2io.v00 module net_sky2.v00 module net_tg3.v00 module net_vmxn.v00 module ohci_usb.v00 module sata_ahc.v00 module sata_ata.v00 module sata_sat.v00 module sata_sat.v01 module sata_sat.v02 module sata_sat.v03 module sata_sat.v04 module scsi_aac.v00 module scsi_adp.v00 module scsi_aic.v00 module scsi_bnx.v00 module scsi_fni.v00 module scsi_hps.v00 module scsi_ips.v00 module scsi_lpf.v00 module scsi_meg.v00 module scsi_meg.v01 module scsi_meg.v02 module scsi_mpt.v00 module scsi_mpt.v01 module scsi_mpt.v02 module scsi_qla.v00 module scsi_qla.v01 module scsi_rst.v00 module uhci_usb.v00 module tools.t00 module xorg.v00 module imgdb.tgz module imgpayld.tgz boot </syntaxhighlight> * The above way to load ESXi, tries to use iPXE's native multiboot, however this currently fails. [http://lists.ipxe.org/pipermail/ipxe-devel/2012-September/001846.html See this iPXE mailing list thread] for more information. == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://forum.ipxe.org -- iPXE Forums, Great resource for finding answers, or asking questions. * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 3534e0d79e83f65ba8235790a200673fca78aab9 Network & Systems Wrangling 0 6 69 46 2012-10-17T00:11:24Z Bpenglase 1 Added link for work setup wikitext text/x-wiki * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). * [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. * [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. * [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics. * [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu. c78c552faa4089b4994b314b05f64de8c93ca4cd 74 69 2013-03-13T23:21:07Z Bpenglase 1 Added link for Wimboot stuff wikitext text/x-wiki * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). * [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. * [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. * [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics. * [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu. * [[Installing Windows over a Network]] - Installing Windows 7 Pro over the network, using iPXE, WIMBoot, and Samba. 8bfc4aa0d59391d5af512ff4820df9eced0ec895 IIS and ASP PXE Booting and Vesamenu 0 13 70 2012-10-17T01:57:11Z Bpenglase 1 Initial submit of the page. wikitext text/x-wiki == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]] Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of ASP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Windows Server 2008 R2 * IIS 7 * Classic ASP Scripting * tftpd32 v4.00 (Service) * iPXE (current GIT master) * Syslinux 4.06_Pre11 * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === IIS Config === <Place holder for the time being> === TFTPD32 Config === <Place holder for the time being> === preboot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim plembed dim clientip dim code dim code1 ' Set code code = "onereallylongcodethatsrandomlygenerated" ' Set Code1 code1 = "secondreallylongcodethatsrandomlygenerated" ' Set IP Subnets that do not get prompted for login dim nologinips(1) nologinips(0) = "10.80.18" ' Subnet for NetApps nologinips(1) = "10.80.38" ' Subnet in Technicians Office ' Get the client's IP Address clientip = request.servervariables("REMOTE_ADDR") ' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes ' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = code then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = code1 then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Compare the current client IP to IPs we shouldn't prompt for login for for i=0 to ubound(nologinips) if instr(clientip, nologinips(i)) then 'Perform functions for clients that don't need to be prompted for login response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf) response.end end if next response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf) response.write("login"&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf) response.end %> </syntaxhighlight> === boot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim user dim pass dim plembed dim testing 'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes 'this is also used to try and hide the user/pass on the command since it's shown in plain text ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Check to see if user is set, and not empty, if it is, then do the same with the password. 'If set, copy the results to variables 'Otherwise fail over with an error code. if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then user = request.querystring("user") if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then pass = request.querystring("pass") else ' If no password is set, fail (either blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1") response.end end if else ' If the username is blank, fail (either left blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1") response.end end if 'Verify user/pass combination 'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu 'Otherwise new variables can be added for more functionality) 'First is user 'cs' - Computing Services if user = "cs" then ' If the password needs to change, change it here if not pass = "a12345B" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 1 shd = 0 end if 'Next user is 'shd' - Student HelpDesk elseif user = "shd" then ' If the password needs to change, change it here if not pass = "B54321a" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 0 shd = 1 end if else response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Check the MAC, this is where we can specify certain PCs get certain things ' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe response.write("#!ipxe" & vbCrLF) Select Case mac Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with. ipxemenu Case "84:2b:2b:xx:xx:xx" ' Dell 980 ipxemenu Case Else ' Fall back and set the pxelinux variables and what variables should work with what menus ' Variable here (current) set based on username provided response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If ' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If End Select sub ipxemenu() response.write(":mainmenu" & vbcrlf) response.write("menu Work Netboot" & vbcrlf) response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf) response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf) response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf) response.write("item --key m memtest Memtest" & vbcrlf) response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf) response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf) response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf) response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf) response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf) response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf) response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf) response.write("item --key p pmagic Parted Magic" & vbcrlf) response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf) response.write("item --gap -- ---------- Other Options ----------" & vbcrlf) response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf) response.write("item --key i installers Installers Submenu" & vbcrlf) response.write("item --key x shell iPXE Shell" & vbcrlf) response.write("item default Default VesaMenu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":dft" & vbcrlf) response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":wddld" & vbcrlf) response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":nboot" & vbcrlf) response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf) response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf) response.write("item --key t tstation Thinstation" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":installers" & vbcrlf) response.write("menu Work Netboot - Installers Menu" & vbcrlf) response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf) response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf) response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf) response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":memtest" & vbcrlf) response.write("chain memtest.0" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":esxi51sl" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) response.write("set 209:string esxi51/esxi.cfg" & vbcrlf) If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write("goto end" & vbcrlf) response.write(":esxi51" & vbcrlf) response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf) response.write("goto end" & vbcrlf) response.write(":wimboot" & vbcrlf) response.write("imgfree" & vbcrlf) response.write("kernel wimboot" & vbcrlf) response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf) response.write("initrd ghostpe/BCD BCD" & vbcrlf) response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf) response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf) response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf) response.write("boot" & vbcrlf) response.write(":7x64" & vbcrlf) response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf) response.write(":7x32" & vbcrlf) response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf) response.write(":default" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write(":end" & vbcrlf) end sub %> </syntaxhighlight> 4dc00d1287174e982b09f3ef1a1e45939d56c910 71 70 2012-10-17T02:04:53Z Bpenglase 1 Added under construction wikitext text/x-wiki <center>'''<big>This is under construction and may not be complete</big>''' </center> == Heading text == == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]] Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of ASP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Windows Server 2008 R2 * IIS 7 * Classic ASP Scripting * tftpd32 v4.00 (Service) * iPXE (current GIT master) * Syslinux 4.06_Pre11 * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === IIS Config === <Place holder for the time being> === TFTPD32 Config === <Place holder for the time being> === preboot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim plembed dim clientip dim code dim code1 ' Set code code = "onereallylongcodethatsrandomlygenerated" ' Set Code1 code1 = "secondreallylongcodethatsrandomlygenerated" ' Set IP Subnets that do not get prompted for login dim nologinips(1) nologinips(0) = "10.80.18" ' Subnet for NetApps nologinips(1) = "10.80.38" ' Subnet in Technicians Office ' Get the client's IP Address clientip = request.servervariables("REMOTE_ADDR") ' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes ' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = code then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = code1 then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Compare the current client IP to IPs we shouldn't prompt for login for for i=0 to ubound(nologinips) if instr(clientip, nologinips(i)) then 'Perform functions for clients that don't need to be prompted for login response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf) response.end end if next response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf) response.write("login"&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf) response.end %> </syntaxhighlight> === boot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim user dim pass dim plembed dim testing 'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes 'this is also used to try and hide the user/pass on the command since it's shown in plain text ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Check to see if user is set, and not empty, if it is, then do the same with the password. 'If set, copy the results to variables 'Otherwise fail over with an error code. if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then user = request.querystring("user") if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then pass = request.querystring("pass") else ' If no password is set, fail (either blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1") response.end end if else ' If the username is blank, fail (either left blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1") response.end end if 'Verify user/pass combination 'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu 'Otherwise new variables can be added for more functionality) 'First is user 'cs' - Computing Services if user = "cs" then ' If the password needs to change, change it here if not pass = "a12345B" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 1 shd = 0 end if 'Next user is 'shd' - Student HelpDesk elseif user = "shd" then ' If the password needs to change, change it here if not pass = "B54321a" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 0 shd = 1 end if else response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Check the MAC, this is where we can specify certain PCs get certain things ' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe response.write("#!ipxe" & vbCrLF) Select Case mac Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with. ipxemenu Case "84:2b:2b:xx:xx:xx" ' Dell 980 ipxemenu Case Else ' Fall back and set the pxelinux variables and what variables should work with what menus ' Variable here (current) set based on username provided response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If ' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If End Select sub ipxemenu() response.write(":mainmenu" & vbcrlf) response.write("menu Work Netboot" & vbcrlf) response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf) response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf) response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf) response.write("item --key m memtest Memtest" & vbcrlf) response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf) response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf) response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf) response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf) response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf) response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf) response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf) response.write("item --key p pmagic Parted Magic" & vbcrlf) response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf) response.write("item --gap -- ---------- Other Options ----------" & vbcrlf) response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf) response.write("item --key i installers Installers Submenu" & vbcrlf) response.write("item --key x shell iPXE Shell" & vbcrlf) response.write("item default Default VesaMenu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":dft" & vbcrlf) response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":wddld" & vbcrlf) response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":nboot" & vbcrlf) response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf) response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf) response.write("item --key t tstation Thinstation" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":installers" & vbcrlf) response.write("menu Work Netboot - Installers Menu" & vbcrlf) response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf) response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf) response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf) response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":memtest" & vbcrlf) response.write("chain memtest.0" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":esxi51sl" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) response.write("set 209:string esxi51/esxi.cfg" & vbcrlf) If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write("goto end" & vbcrlf) response.write(":esxi51" & vbcrlf) response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf) response.write("goto end" & vbcrlf) response.write(":wimboot" & vbcrlf) response.write("imgfree" & vbcrlf) response.write("kernel wimboot" & vbcrlf) response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf) response.write("initrd ghostpe/BCD BCD" & vbcrlf) response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf) response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf) response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf) response.write("boot" & vbcrlf) response.write(":7x64" & vbcrlf) response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf) response.write(":7x32" & vbcrlf) response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf) response.write(":default" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write(":end" & vbcrlf) end sub %> </syntaxhighlight> 6e923137d16a62b0771bd2211fa8e44733d197c3 72 71 2012-10-17T02:18:50Z Bpenglase 1 Submitted rest of the files. Will comment it all later. wikitext text/x-wiki <center>'''<big>This is under construction and may not be complete</big>''' </center> == Heading text == == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]] Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of ASP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Windows Server 2008 R2 * IIS 7 * Classic ASP Scripting * tftpd32 v4.00 (Service) * iPXE (current GIT master) * Syslinux 4.06_Pre11 * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === IIS Config === <Place holder for the time being> === TFTPD32 Config === <Place holder for the time being> === preboot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim plembed dim clientip dim code dim code1 ' Set code code = "onereallylongcodethatsrandomlygenerated" ' Set Code1 code1 = "secondreallylongcodethatsrandomlygenerated" ' Set IP Subnets that do not get prompted for login dim nologinips(1) nologinips(0) = "10.80.18" ' Subnet for NetApps nologinips(1) = "10.80.38" ' Subnet in Technicians Office ' Get the client's IP Address clientip = request.servervariables("REMOTE_ADDR") ' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes ' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = code then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = code1 then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Compare the current client IP to IPs we shouldn't prompt for login for for i=0 to ubound(nologinips) if instr(clientip, nologinips(i)) then 'Perform functions for clients that don't need to be prompted for login response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf) response.end end if next response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf) response.write("login"&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf) response.end %> </syntaxhighlight> === boot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim user dim pass dim plembed dim testing 'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes 'this is also used to try and hide the user/pass on the command since it's shown in plain text ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Check to see if user is set, and not empty, if it is, then do the same with the password. 'If set, copy the results to variables 'Otherwise fail over with an error code. if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then user = request.querystring("user") if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then pass = request.querystring("pass") else ' If no password is set, fail (either blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1") response.end end if else ' If the username is blank, fail (either left blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1") response.end end if 'Verify user/pass combination 'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu 'Otherwise new variables can be added for more functionality) 'First is user 'cs' - Computing Services if user = "cs" then ' If the password needs to change, change it here if not pass = "a12345B" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 1 shd = 0 end if 'Next user is 'shd' - Student HelpDesk elseif user = "shd" then ' If the password needs to change, change it here if not pass = "B54321a" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 0 shd = 1 end if else response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Check the MAC, this is where we can specify certain PCs get certain things ' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe response.write("#!ipxe" & vbCrLF) Select Case mac Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with. ipxemenu Case "84:2b:2b:xx:xx:xx" ' Dell 980 ipxemenu Case Else ' Fall back and set the pxelinux variables and what variables should work with what menus ' Variable here (current) set based on username provided response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If ' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If End Select sub ipxemenu() response.write(":mainmenu" & vbcrlf) response.write("menu Work Netboot" & vbcrlf) response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf) response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf) response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf) response.write("item --key m memtest Memtest" & vbcrlf) response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf) response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf) response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf) response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf) response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf) response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf) response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf) response.write("item --key p pmagic Parted Magic" & vbcrlf) response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf) response.write("item --gap -- ---------- Other Options ----------" & vbcrlf) response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf) response.write("item --key i installers Installers Submenu" & vbcrlf) response.write("item --key x shell iPXE Shell" & vbcrlf) response.write("item default Default VesaMenu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":dft" & vbcrlf) response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":wddld" & vbcrlf) response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":nboot" & vbcrlf) response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf) response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf) response.write("item --key t tstation Thinstation" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":installers" & vbcrlf) response.write("menu Work Netboot - Installers Menu" & vbcrlf) response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf) response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf) response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf) response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":memtest" & vbcrlf) response.write("chain memtest.0" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":esxi51sl" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) response.write("set 209:string esxi51/esxi.cfg" & vbcrlf) If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write("goto end" & vbcrlf) response.write(":esxi51" & vbcrlf) response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf) response.write("goto end" & vbcrlf) response.write(":wimboot" & vbcrlf) response.write("imgfree" & vbcrlf) response.write("kernel wimboot" & vbcrlf) response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf) response.write("initrd ghostpe/BCD BCD" & vbcrlf) response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf) response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf) response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf) response.write("boot" & vbcrlf) response.write(":7x64" & vbcrlf) response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf) response.write(":7x32" & vbcrlf) response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf) response.write(":default" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write(":end" & vbcrlf) end sub %> </syntaxhighlight> === mainmenu.ipxe === <syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS"> ui vesamenu.c32 menu title Network Boot Menu for Work menu autoboot System will boot to Ghost in # seconds menu master passwd MasterPassword menu background backgrounds/pxeboot-800.png menu resolution 800 600 prompt 0 timeout 1000 menu timeoutrow 99 allowoptions 0 menu rows 25 menu helpmsgrow -1 menu color title 0 #ff00388b #00FFFFFF none menu color unsel 0 #ffffffff #88000000 std menu color sel 0 #ff000000 #88c1c1c1 none menu color hotkey 0 #ff0067ff #80000000 std menu color hotsel 0 #ff000000 #88c1c1c1 none menu color disabled 0 #ff0067ff #88000000 std Label GhostPE menu label Ghost Tools / PE Environments: menu disable label PE menu indent 2 menu label ^1 Ghost PE Boot Disk (08/06/12) menu default kernel memdisk append iso raw initrd PEBoot-08_06_12.iso label Alt-PE menu indent 4 menu label Ghost PEBoot AltBoot (08/06/12) COM32 linux.c32 APPEND memdisk initrd=PEBoot-08_06_12.iso iso Label HardDiag menu label Hardware Diagnostics: menu disable label Memtest menu indent 2 menu label ^2 Memtest86+ v4.20 kernel memtest86-420 label DFT menu indent 2 menu label ^3 Drive Fitness Test v4.16 kernel memdisk append initrd=dft32_v416_b00_install.IMG floppy label WDDLD menu indent 2 menu label ^4 WD Data Lifeguard Diagnostic v5.04f kernel memdisk append iso raw initrd Diag504fCD.iso label SEATOOLS menu indent 2 menu label ^5 Seagate Seatools for DOS v2.23 kernel memdisk append iso raw initrd SeaToolsDOS223ALL.ISO label HDT menu indent 2 menu label ^6 Hardware Detection Tool kernel hdt.c32 label UBCD menu indent 2 menu label ^7 Ultimate Boot CD v5.1.1 kernel memdisk append iso raw initrd ubcd511.iso label SpinRite menu indent 2 menu label ^8 SpinRite v6.0 kernel memdisk append iso raw initrd spinrite.iso label DiskWipe menu label Disk Utilities: menu disable label QuickWipe menu indent 2 menu label ^9 Quick Disk Wipe (Default: Disk 0) kernel memdisk append floppy initrd=wipe2.img label DBAN menu indent 2 menu label ^0 Darik's Boot And Nuke (DBAN) v2.2.6 kernel memdisk append iso raw edd=off initrd dban-2.2.6_i586-fixed.iso label SalvationHDD menu indent 2 menu label ^S Salvation HDD Scan & Restore v3.0 kernel memdisk append floppy initrd=sal-hdd-sr.img label PartedMagic menu indent 2 menu label ^P Parted Magic linux pmagic/bzImage append initrd=pmagic/initramfs edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw vga=791 loglevel=0 mac_loop=256 label GParted menu indent 2 menu label ^G GParted (Gnome Partition Editor) kernel gparted/vmlinuz append initrd=gparted/initrd.img boot=live config union=aufs noswap noprompt vga=788 fetch=http://netboot.example.com/gparted/filesystem.squashfs noapic edd=off label OtherNetboot menu label Other Netboot Systems: menu disable label Citrix menu indent 2 menu label ^C Boot to Citrix Provisioning Service (citrix-dp) com32 pxechn.c32 append 10.133.2.232::ardbp32.bin label Thinstation menu indent 2 menu label ^T Thinstation kernel thinstation/vmlinuz append initrd=thinstation/initrd video=uvesafb:1024x768-32,ywrap splash=off console=tty1 loglevel=7 LM=3 label Others menu label Other Options: menu disable label Installers menu label ^E Installers SubMenu menu indent 2 kernel vesamenu.c32 append installers.conf label BIOS menu disabled menu label ^B BIOS Updates SubMenu menu indent 2 kernel vesamenu.c32 append bios/biosupdates.conf Label Testing Menu Label ^T Testing SubMenu menu indent 2 kernel vesamenu.c32 append testing.conf label MenuExit menu indent 2 menu label ^Q Exit Menu System - PXELinux Boot Prompt menu quit </syntaxhighlight> === installers.conf === <syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS"> ui vesamenu.c32 menu title Network Installers Menu for Work menu master passwd MasterPassword menu background backgrounds/pxeboot-800.png menu resolution 800 600 prompt 0 menu timeoutrow 99 allowoptions 0 menu rows 22 menu helpmsgrow -1 menu color title 0 #ff00388b #00FFFFFF none menu color unsel 0 #ffffffff #88000000 std menu color sel 0 #ff000000 #88c1c1c1 none menu color hotkey 0 #ff0067ff #80000000 std menu color hotsel 0 #ff000000 #88c1c1c1 none menu color disabled 0 #ff0067ff #88000000 std Label VMWare menu label VMWare Installers: menu disable label ESXi5 menu indent 2 menu label ^1 VMWare ESXi HyperVisor 5.1.0 menu default kernel esxi51/mboot.c32 append -c /esxi51/boot.cfg label DebianAMD64 menu label ^2 Debian Squeeze AMD64 Netinstall menu indent 2 kernel debian-installer/amd64/linux append vga=788 initrd=debian-installer/amd64/initrd.gz label DebianAMD64Rescue menu label ^3 Debian Squeeze AMD64 Rescue mode menu indent 2 kernel debian-installer/amd64/linux append vga=788 initrd=debian-installer/amd64/initrd.gz rescue/enable=true label Debiani386 menu label ^4 Debian Squeeze i386 Netinstall menu indent 2 kernel debian-installer/i386/linux append vga=788 initrd=debian-installer/i386/initrd.gz label Debiani386Rescue menu label ^5 Debian Squeeze i386 Rescue Mode menu indent 2 kernel debian-installer/i386/linux append vga=788 initrd=debian-installer/i386/initrd.gz rescue/enable=true label MainMenu menu indent 2 menu label ^Q Return to Main Menu kernel vesamenu.c32 append mainmenu.ipxe </syntaxhighlight> === mainmenu-shd.ipxe === <syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS"> ui vesamenu.c32 menu title Network Boot Menu for Work menu master passwd MasterPassword menu background backgrounds/pxeboot-800.png menu resolution 800 600 prompt 0 timeout 1000 menu timeoutrow 99 allowoptions 0 #menu vshift 0 menu rows 23 menu helpmsgrow -1 menu color title 0 #ff00388b #00FFFFFF none menu color unsel 0 #ffffffff #88000000 std menu color sel 0 #ff000000 #88c1c1c1 none menu color hotkey 0 #ff0067ff #80000000 std menu color hotsel 0 #ff000000 #88c1c1c1 none menu color disabled 0 #ff0067ff #88000000 std Label HardDiag menu label Hardware Diagnostics: menu disable label Memtest menu indent 2 menu label ^1 Memtest86+ v4.20 kernel memtest86-420 label DFT menu indent 2 menu label ^2 Drive Fitness Test v4.16 kernel memdisk append initrd=dft32_v416_b00_install.IMG floppy label WDDLD menu indent 2 menu label ^3 WD Data Lifeguard Diagnostic v5.04f kernel memdisk append iso raw initrd Diag504fCD.iso label SEATOOLS menu indent 2 menu label ^4 Seagate Seatools for DOS v2.23 kernel memdisk append iso raw initrd SeaToolsDOS223ALL.ISO label HDT menu indent 2 menu label ^5 Hardware Detection Tool kernel hdt.c32 label UBCD menu indent 2 menu label ^6 Ultimate Boot CD v5.1.1 kernel memdisk append iso raw initrd ubcd511.iso label Rescue menu label System Rescue Utilities menu disable label Avira menu indent 2 menu disable menu label ^7 Avira AntiVir Rescue System - Currently Broken kernel memdisk append iso raw initrd rescue_system-common-en.iso label Others menu label Other Options: menu disable label MenuExit menu indent 2 menu passwd zaxscd menu label ^Q Exit Menu System - PXELinux Boot Prompt menu quit </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://forum.ipxe.org -- iPXE Forums, Great resource for finding answers, or asking questions. * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! * http://www.syslinux.org/wiki/index.php/Menu -- Syslinux's Menu documentation == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 5b7956c74e750d63354bed5160dc4768a95f0930 73 72 2012-10-17T02:19:22Z Bpenglase 1 removed extra header wikitext text/x-wiki <center>'''<big>This is under construction and may not be complete</big>''' </center> == Intro == PXE (Preboot Execution Environment) Booting, or just Network booting in general is very interesting, at least to me, and a few others. As I believe it was Marty Connor in [http://www.youtube.com/watch?v=GofOqhO6VVM this awesome video "gPXE: Modern FOSS Network Booting"] said that some people get really excited over booting machines over networks (including the Internet!) while others... not so much. Well, I'm one of those people who gets really excited over the idea of booting machines over a network, and I can't really put my finger on why, it's just awesome to me. So, I wanted to document the netboot setups that I use at my home, and my work. This entry consists of my work setup. My home setup is [[PXE Booting and Utilities Menu|detailed here]] Now, network booting isn't for everyone, and it doesn't fit every situation, so your mileage will vary greatly. My work setup consists of [http://ipxe.org/ iPXE], ASP Scripting, [http://www.syslinux.org Syslinux], and different separate utilities. All of this is detailed below... so lets begin! == What does this page assume? == * You have a working network * You control your DHCP Server * You have control of your DNS server * You have a working webserver * Basic understanding of ASP * Have a basic understand of whats involved with PXE Booting, even if it's [http://en.wikipedia.org/wiki/Preboot_Execution_Environment skimming over the Wikipedia page] * Have a machine that is capable of picking the network card to boot from, via PXE (On most Dell systems, you need to go into the BIOS, Integrated Peripherals, and mark the NIC as "On W/ PXE", not just "On", or "On W/ ImageServer" == My Environment == * Windows Server 2008 R2 * IIS 7 * Classic ASP Scripting * tftpd32 v4.00 (Service) * iPXE (current GIT master) * Syslinux 4.06_Pre11 * Misc Utilities like Drive Fitness Test, SeaTools, Memtest, etc. == The Basic Process == -- My Setup # Computer powers on, and selects the NIC to boot from, either via interaction, or it being the first device # The native PXE Stack (iPXE (flashed onto the ROM/BIOS), Intel, Broadom, Realtek, etc) brings up the network card, does a DHCP Request, while also requesting, at least, options 66 and 67 # DHCP Server responds with an IP, and the two options # The PXE Stack then tried to contact the server provided in option 66, to retrieve the file specified in option 67, which in this case is iPXE (for non-iPXE clients), over TFTP # iPXE then unloads the native PXE stack (to a degree), and takes over, issuing it's own DHCP Request, again requesting, among other options, 66 and 67 # The DHCP Server responds with (typically) the same IP address, but now detects that the client is iPXE, and passes a different option 67. # iPXE then boots to the URL passed in option 67 this time (via HTTP), and that script then directs it what to do. == Files == === IIS Config === <Place holder for the time being> === TFTPD32 Config === <Place holder for the time being> === preboot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim plembed dim clientip dim code dim code1 ' Set code code = "onereallylongcodethatsrandomlygenerated" ' Set Code1 code1 = "secondreallylongcodethatsrandomlygenerated" ' Set IP Subnets that do not get prompted for login dim nologinips(1) nologinips(0) = "10.80.18" ' Subnet for NetApps nologinips(1) = "10.80.38" ' Subnet in Technicians Office ' Get the client's IP Address clientip = request.servervariables("REMOTE_ADDR") ' Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes ' this is also used to try and hide the user/pass on the command since it's shown in plain text in the URL ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = code then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = code1 then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Compare the current client IP to IPs we shouldn't prompt for login for for i=0 to ubound(nologinips) if instr(clientip, nologinips(i)) then 'Perform functions for clients that don't need to be prompted for login response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Bypassing Login, Autologging in as CS."&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=cs&pass=a12345B&plembed="&plembed&"&code1="&code1&vbcrlf) response.end end if next response.write("#!ipxe"&vbcrlf) response.write("echo On IP "&clientip&" -- Forcing Login."&vbcrlf) response.write("login"&vbcrlf) response.write("chain -ar http://netboot.example.com/boot.asp?MAC="&mac&"&code="&code&"&user=${username:uristring}&pass=${password:uristring}&plembed="&plembed&"&code1="&code1&vbcrlf) response.end %> </syntaxhighlight> === boot.asp === <syntaxhighlight lang="asp" line="GESHI_NORMAL_LINE_NUMBERS"> <% response.contenttype="text/plain" dim mac dim user dim pass dim plembed dim testing 'Check to see if the PXE boot thats hitting us is authorized, the boot will embed two random codes 'this is also used to try and hide the user/pass on the command since it's shown in plain text ' Check Code0 if not request.querystring("code").count = 0 then if request.querystring("code") = "onereallylongcodethatsrandomlygenerated" then ' Check Code1 if not isEmpty(request.querystring("code1")) then if not request.querystring("code1") = "secondreallylongcodethatsrandomlygenerated" then ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 001 - This PXEBoot is not authorized." & vbcrlf & "exit 1") response.end end if end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 002 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if else ' Fail to boot, don't offer login screen again response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 003 - This PXEBoot is not authorized."& vbcrlf & "exit 1") response.end end if 'Check to see if user is set, and not empty, if it is, then do the same with the password. 'If set, copy the results to variables 'Otherwise fail over with an error code. if not request.querystring("user").count = 0 and not isEmpty(request.querystring("user")) then user = request.querystring("user") if not request.querystring("pass").count = 0 and not isEmpty(request.querystring("pass")) then pass = request.querystring("pass") else ' If no password is set, fail (either blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 004 - No Password Set."& vbcrlf & "exit 1") response.end end if else ' If the username is blank, fail (either left blank, or login command was not issued) response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 005 - No Username Set."& vbcrlf & "exit 1") response.end end if 'Verify user/pass combination 'Other users can be added here, following the same code (can use the cs or shd variables if returning the same menu 'Otherwise new variables can be added for more functionality) 'First is user 'cs' - Computing Services if user = "cs" then ' If the password needs to change, change it here if not pass = "a12345B" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 006 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 1 shd = 0 end if 'Next user is 'shd' - Student HelpDesk elseif user = "shd" then ' If the password needs to change, change it here if not pass = "B54321a" then response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 007 - Wrong Password." & vbcrlf & "exit 1") response.end else ' Set the proper code for which menu (or other functions) should be returned to the user cs = 0 shd = 1 end if else response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 008 - Invalid Username." & vbcrlf & "exit 1") response.end end if 'Get MAC Address into a variable ' This should always be handed over to this script. If not isEmpty(request.querystring("MAC")) Then mac = request.querystring("MAC") else ' If no MAC found, it's most likely a bad script, or unauthorized netboot that has somehow gotten this far response.write("#!ipxe" & vbcrlf & "echo Boot Error Code: Error 009 - MAC Not listed."& vbcrlf & "exit 1") response.end End If ' Find out of Pxelinux is embedded or not If not isEmpty(request.querystring("plembed")) Then plembed = request.querystring("plembed") else plembed = 0 End If ' Check the MAC, this is where we can specify certain PCs get certain things ' This was changed to #!ipxe on 5/7/12, if gPXE is still in use, it may fail, however most builds are now ipxe response.write("#!ipxe" & vbCrLF) Select Case mac Case "00:0c:29:xx:xx:xx" ' This is a VM for testing the netboot with. ipxemenu Case "84:2b:2b:xx:xx:xx" ' Dell 980 ipxemenu Case Else ' Fall back and set the pxelinux variables and what variables should work with what menus ' Variable here (current) set based on username provided response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If ' If pxelinux is embedded, load it from the embedded image, otherwise pull it from the server If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If End Select sub ipxemenu() response.write(":mainmenu" & vbcrlf) response.write("menu Work Netboot" & vbcrlf) response.write("item --gap -- ----------- Ghost Boots -----------" & vbcrlf) response.write("item --key w wimboot Symantec Ghost PE via WIMBoot" & vbcrlf) response.write("item --gap -- ------ Hardware Diagnostics -------" & vbcrlf) response.write("item --key m memtest Memtest" & vbcrlf) response.write("item --key d dft Drive Fitness Test v4.16" & vbcrlf) response.write("item --key l wddld WD Data Lifegaurd Diagnostics v5.04f" & vbcrlf) response.write("item --key s seatools Seagate Seatools for DOS v2.23" & vbcrlf) response.write("item --gap -- --------- Disk Utilities ----------" & vbcrlf) response.write("item --key q qwipe Quick Wipe (Default Disk: 0)" & vbcrlf) response.write("item --key a dban Darik's Boot and Nuke (DBAN) v2.2.6" & vbcrlf) response.write("item --key h shdd Salvation HDD Scan and Restore v3.0" & vbcrlf) response.write("item --key p pmagic Parted Magic" & vbcrlf) response.write("item --key g gparted GParted (Gnome Partition Editor)" & vbcrlf) response.write("item --gap -- ---------- Other Options ----------" & vbcrlf) response.write("item --key o nboot Other Netboot Systems Menu" & vbcrlf) response.write("item --key i installers Installers Submenu" & vbcrlf) response.write("item --key x shell iPXE Shell" & vbcrlf) response.write("item default Default VesaMenu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":dft" & vbcrlf) response.write("sanboot --drive=0x00 dft32_v416_b00_install.IMG" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":wddld" & vbcrlf) response.write("sanboot --drive=0xa0 Diag504fCD.iso" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":nboot" & vbcrlf) response.write("menu Work Netboot - Other Netboot Systems" & vbcrlf) response.write("item --key c citrix Citrix Provisioning Service (Citrix-DP)" & vbcrlf) response.write("item --key t tstation Thinstation" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":installers" & vbcrlf) response.write("menu Work Netboot - Installers Menu" & vbcrlf) response.write("item --key 3 7x32 Windows 7 32bit Installer" & vbcrlf) response.write("item --key 6 7x64 Windows 7 64bit Installer" & vbcrlf) response.write("item --key p esxi51sl ESXi 5.1 Installer via PXELinux" & vbcrlf) response.write("item --key i esxi51 ESXi 5.1 Installer native iPXE" & vbcrlf) response.write("item --key r mainmenu Return to Main Menu" & vbcrlf) response.write("choose label && goto ${label}" & vbcrlf) response.write(":memtest" & vbcrlf) response.write("chain memtest.0" & vbcrlf) response.write("goto mainmenu" & vbcrlf) response.write(":esxi51sl" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) response.write("set 209:string esxi51/esxi.cfg" & vbcrlf) If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write("goto end" & vbcrlf) response.write(":esxi51" & vbcrlf) response.write("chain http://netboot.example.com/esxi51/esxi51.ipxe" & vbcrlf) response.write("goto end" & vbcrlf) response.write(":wimboot" & vbcrlf) response.write("imgfree" & vbcrlf) response.write("kernel wimboot" & vbcrlf) response.write("initrd ghostpe/bootmgr.exe bootmgr.exe" & vbcrlf) response.write("initrd ghostpe/BCD BCD" & vbcrlf) response.write("initrd ghostpe/fonts/chs_boot.ttf chs_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/cht_boot.ttf cht_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/kor_boot.ttf kor_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/jpn_boot.ttf jpn_boot.ttf" & vbcrlf) response.write("initrd ghostpe/fonts/wgl4_boot.ttf wgl4_boot.ttf"& vbcrlf) response.write("initrd ghostpe/boot.sdi boot.sdi" & vbcrlf) response.write("initrd ghostpe/boot.wim boot.wim" & vbcrlf) response.write("boot" & vbcrlf) response.write(":7x64" & vbcrlf) response.write("sanboot --drive 0xA0 --no-describe http://netboot.example.com/sysinstalls/W7ENTx64.iso" & vbcrlf) response.write(":7x32" & vbcrlf) response.write("sanboot --drive 0x81 --no-describe http://netboot.example.com/sysinstalls/W7ENTx32.iso" & vbcrlf) response.write(":default" & vbcrlf) response.write("set 210:string http://netboot.example.com/" & vbcrlf) If cs = 1 Then response.write("set 209:string mainmenu.ipxe" & vbcrlf) ElseIf shd = 1 Then response.write("set 209:string mainmenu-shd.ipxe" & vbcrlf) End If If plembed = 1 Then response.write("imgload pxelinux.0" & vbcrlf) response.write("imgexec pxelinux.0" & vbcrlf) Else response.write("chain ${210:string}pxelinux.0" & vbcrlf) End If response.write(":end" & vbcrlf) end sub %> </syntaxhighlight> === mainmenu.ipxe === <syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS"> ui vesamenu.c32 menu title Network Boot Menu for Work menu autoboot System will boot to Ghost in # seconds menu master passwd MasterPassword menu background backgrounds/pxeboot-800.png menu resolution 800 600 prompt 0 timeout 1000 menu timeoutrow 99 allowoptions 0 menu rows 25 menu helpmsgrow -1 menu color title 0 #ff00388b #00FFFFFF none menu color unsel 0 #ffffffff #88000000 std menu color sel 0 #ff000000 #88c1c1c1 none menu color hotkey 0 #ff0067ff #80000000 std menu color hotsel 0 #ff000000 #88c1c1c1 none menu color disabled 0 #ff0067ff #88000000 std Label GhostPE menu label Ghost Tools / PE Environments: menu disable label PE menu indent 2 menu label ^1 Ghost PE Boot Disk (08/06/12) menu default kernel memdisk append iso raw initrd PEBoot-08_06_12.iso label Alt-PE menu indent 4 menu label Ghost PEBoot AltBoot (08/06/12) COM32 linux.c32 APPEND memdisk initrd=PEBoot-08_06_12.iso iso Label HardDiag menu label Hardware Diagnostics: menu disable label Memtest menu indent 2 menu label ^2 Memtest86+ v4.20 kernel memtest86-420 label DFT menu indent 2 menu label ^3 Drive Fitness Test v4.16 kernel memdisk append initrd=dft32_v416_b00_install.IMG floppy label WDDLD menu indent 2 menu label ^4 WD Data Lifeguard Diagnostic v5.04f kernel memdisk append iso raw initrd Diag504fCD.iso label SEATOOLS menu indent 2 menu label ^5 Seagate Seatools for DOS v2.23 kernel memdisk append iso raw initrd SeaToolsDOS223ALL.ISO label HDT menu indent 2 menu label ^6 Hardware Detection Tool kernel hdt.c32 label UBCD menu indent 2 menu label ^7 Ultimate Boot CD v5.1.1 kernel memdisk append iso raw initrd ubcd511.iso label SpinRite menu indent 2 menu label ^8 SpinRite v6.0 kernel memdisk append iso raw initrd spinrite.iso label DiskWipe menu label Disk Utilities: menu disable label QuickWipe menu indent 2 menu label ^9 Quick Disk Wipe (Default: Disk 0) kernel memdisk append floppy initrd=wipe2.img label DBAN menu indent 2 menu label ^0 Darik's Boot And Nuke (DBAN) v2.2.6 kernel memdisk append iso raw edd=off initrd dban-2.2.6_i586-fixed.iso label SalvationHDD menu indent 2 menu label ^S Salvation HDD Scan & Restore v3.0 kernel memdisk append floppy initrd=sal-hdd-sr.img label PartedMagic menu indent 2 menu label ^P Parted Magic linux pmagic/bzImage append initrd=pmagic/initramfs edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw vga=791 loglevel=0 mac_loop=256 label GParted menu indent 2 menu label ^G GParted (Gnome Partition Editor) kernel gparted/vmlinuz append initrd=gparted/initrd.img boot=live config union=aufs noswap noprompt vga=788 fetch=http://netboot.example.com/gparted/filesystem.squashfs noapic edd=off label OtherNetboot menu label Other Netboot Systems: menu disable label Citrix menu indent 2 menu label ^C Boot to Citrix Provisioning Service (citrix-dp) com32 pxechn.c32 append 10.133.2.232::ardbp32.bin label Thinstation menu indent 2 menu label ^T Thinstation kernel thinstation/vmlinuz append initrd=thinstation/initrd video=uvesafb:1024x768-32,ywrap splash=off console=tty1 loglevel=7 LM=3 label Others menu label Other Options: menu disable label Installers menu label ^E Installers SubMenu menu indent 2 kernel vesamenu.c32 append installers.conf label BIOS menu disabled menu label ^B BIOS Updates SubMenu menu indent 2 kernel vesamenu.c32 append bios/biosupdates.conf Label Testing Menu Label ^T Testing SubMenu menu indent 2 kernel vesamenu.c32 append testing.conf label MenuExit menu indent 2 menu label ^Q Exit Menu System - PXELinux Boot Prompt menu quit </syntaxhighlight> === installers.conf === <syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS"> ui vesamenu.c32 menu title Network Installers Menu for Work menu master passwd MasterPassword menu background backgrounds/pxeboot-800.png menu resolution 800 600 prompt 0 menu timeoutrow 99 allowoptions 0 menu rows 22 menu helpmsgrow -1 menu color title 0 #ff00388b #00FFFFFF none menu color unsel 0 #ffffffff #88000000 std menu color sel 0 #ff000000 #88c1c1c1 none menu color hotkey 0 #ff0067ff #80000000 std menu color hotsel 0 #ff000000 #88c1c1c1 none menu color disabled 0 #ff0067ff #88000000 std Label VMWare menu label VMWare Installers: menu disable label ESXi5 menu indent 2 menu label ^1 VMWare ESXi HyperVisor 5.1.0 menu default kernel esxi51/mboot.c32 append -c /esxi51/boot.cfg label DebianAMD64 menu label ^2 Debian Squeeze AMD64 Netinstall menu indent 2 kernel debian-installer/amd64/linux append vga=788 initrd=debian-installer/amd64/initrd.gz label DebianAMD64Rescue menu label ^3 Debian Squeeze AMD64 Rescue mode menu indent 2 kernel debian-installer/amd64/linux append vga=788 initrd=debian-installer/amd64/initrd.gz rescue/enable=true label Debiani386 menu label ^4 Debian Squeeze i386 Netinstall menu indent 2 kernel debian-installer/i386/linux append vga=788 initrd=debian-installer/i386/initrd.gz label Debiani386Rescue menu label ^5 Debian Squeeze i386 Rescue Mode menu indent 2 kernel debian-installer/i386/linux append vga=788 initrd=debian-installer/i386/initrd.gz rescue/enable=true label MainMenu menu indent 2 menu label ^Q Return to Main Menu kernel vesamenu.c32 append mainmenu.ipxe </syntaxhighlight> === mainmenu-shd.ipxe === <syntaxhighlight lang="text" line="GESHI_NORMAL_LINE_NUMBERS"> ui vesamenu.c32 menu title Network Boot Menu for Work menu master passwd MasterPassword menu background backgrounds/pxeboot-800.png menu resolution 800 600 prompt 0 timeout 1000 menu timeoutrow 99 allowoptions 0 #menu vshift 0 menu rows 23 menu helpmsgrow -1 menu color title 0 #ff00388b #00FFFFFF none menu color unsel 0 #ffffffff #88000000 std menu color sel 0 #ff000000 #88c1c1c1 none menu color hotkey 0 #ff0067ff #80000000 std menu color hotsel 0 #ff000000 #88c1c1c1 none menu color disabled 0 #ff0067ff #88000000 std Label HardDiag menu label Hardware Diagnostics: menu disable label Memtest menu indent 2 menu label ^1 Memtest86+ v4.20 kernel memtest86-420 label DFT menu indent 2 menu label ^2 Drive Fitness Test v4.16 kernel memdisk append initrd=dft32_v416_b00_install.IMG floppy label WDDLD menu indent 2 menu label ^3 WD Data Lifeguard Diagnostic v5.04f kernel memdisk append iso raw initrd Diag504fCD.iso label SEATOOLS menu indent 2 menu label ^4 Seagate Seatools for DOS v2.23 kernel memdisk append iso raw initrd SeaToolsDOS223ALL.ISO label HDT menu indent 2 menu label ^5 Hardware Detection Tool kernel hdt.c32 label UBCD menu indent 2 menu label ^6 Ultimate Boot CD v5.1.1 kernel memdisk append iso raw initrd ubcd511.iso label Rescue menu label System Rescue Utilities menu disable label Avira menu indent 2 menu disable menu label ^7 Avira AntiVir Rescue System - Currently Broken kernel memdisk append iso raw initrd rescue_system-common-en.iso label Others menu label Other Options: menu disable label MenuExit menu indent 2 menu passwd zaxscd menu label ^Q Exit Menu System - PXELinux Boot Prompt menu quit </syntaxhighlight> == Resources Used == * http://ipxe.org -- iPXE's main site, which contains a ton of information (specifics are linked throughout the entry too) * http://forum.ipxe.org -- iPXE Forums, Great resource for finding answers, or asking questions. * http://lists.ipxe.org/pipermail/ipxe-devel/ -- iPXE Mailing List * http://etherboot.org -- Etherboot/gPXE, iPXE's predecessor. This is what I used when I first setup my netboot, and a lot of the setup came from here. Other issues aside, iPXE is a fork, and is being updated. Most of the information still applies to iPXE. * http://www.networksorcery.com/enp/protocol/bootp/options.htm -- General DHCP Options * http://www.vcritical.com/2011/07/vmware-esxi-5-interactive-pxe-installation-improvements/ -- Linked above, but want to again. This is a good article on how to get ESXi installer to run over PXE. * I'm sure there have been many over the years. As I come up with more, I will add them. * https://gist.github.com/2234639 -- Robin Smidsrød's iPXE menu * http://www.youtube.com/watch?v=GofOqhO6VVM -- Linked above, but linking again, as it's an Awesome presentation! * http://www.syslinux.org/wiki/index.php/Menu -- Syslinux's Menu documentation == Fin == These files may end up on [https://github.com/bpenglase my github] at some point. If/when they do, I'll note it here. iPXE is EXTREMELY powerful, especially with the [http://ipxe.org/scripting embedded scripting]. There is so much that can be done, it's hard to go into details, just because what you can do is so vast! A perfect example of this is Robin's iPXE menu linked to above. He does some awesome stuff! I'm always looking to expand the netboot. Be adding diag utils, playing around with new options, or just plain tweaking it. In the above boot.php, a few of the things I want to tweak, is instead of referencing the name boot.example.com all the time, have it pull the PHP server variable. This way if you have a different hostname internal/external, as long as you set it once (say in a script, or via DHCP), it will always reference that server. One thing to note with iPXE, is you can also embed the scripts into it. In my work netboot (coming soon!), I embed pxelinux.0 and a small script. This will be explained more in that post, but one thing to note, is you can embed a script that does DHCP, then chains to your server at home. As long as you have external access to that box, and flash the resulting iPXE to a USB drive, or CD, you can boot any machine anywhere in the world. For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. d0841f999f701991d6ed3681659fd3f5bf70c90d Installing Windows over a Network 0 14 75 2013-03-13T23:41:13Z Bpenglase 1 New Page! Laying out the format. wikitext text/x-wiki <big>== Under Construction! ==</big> == Intro == Intro Text == What does this page assume? == Assumptions == My Environment == Environment == The Basic Process == Da Basics == Files == Files == Resources Used == Resources == Fin == Final words For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. 02133c8ef5f2818bf1b8c16bc48641d33f552e7c 76 75 2013-03-13T23:43:33Z Bpenglase 1 wikitext text/x-wiki <Center> <big><big>Under Construction!!!</big></big> </center> == Intro == Intro Text == What does this page assume? == Assumptions == My Environment == Environment == The Basic Process == Da Basics == Files == Files == Resources Used == Resources == Fin == Final words For contacting myself (for complaints/improvements/suggestions), or others who use iPXE, there is the IRC channel, irc.freenode.net, #ipxe. I'm pretty much always in there as Sedorox. The developers also hang out there, and other users too, who do all sorts of fun network booting things. Come visit! Hopefully this helps someone better understand iPXE and netbooting, or at the very least, serves as an example on what you can do. ffc586b58dfd37336604d9ab0da9e10861283034 Getting *nix to Netboot Macs 0 5 77 17 2013-12-13T17:02:12Z Bpenglase 1 /* Fin */ wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/article.php?story=20061220102102611 article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times == Fin == * <strike>Once OSXDeployment.com is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.</strike> This site has been rolled into AFP548. * I have learned more about BSDP then I ever wanted to know :) * I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox. 4788d98f99ca355e40699579b6fdaf3fd54b9dc7 78 77 2013-12-13T17:06:13Z Bpenglase 1 /* Resources Used to Complete this */ Updated dead URL wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by [https://jamfnation.jamfsoftware.com/article.html?id=64 JAMF Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/2006/12/20/howto-configure-gnulinux-to-provide-bsdp-netboot-services/ article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times == Fin == * <strike>Once OSXDeployment.com is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.</strike> This site has been rolled into AFP548. * I have learned more about BSDP then I ever wanted to know :) * I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox. dde3de76b456177d2faa59636e2faccbc9a2181f 79 78 2013-12-13T17:19:24Z Bpenglase 1 /* Caveats */ wikitext text/x-wiki == Intro == So, you wanted to move your netbooting off of a OS X box, and onto a box running [http://www.isc.org/software/dhcp ISC DHCP], for one reason or another. Well, you stumbled on the right page! This should help you get booting from a ISC DHCP based DHCP server working with just a little bit of work. == What is this all about? == For any number of reasons, you may want to move the server(s) handling your Mac netboot to [http://www.isc.org/software/dhcp ISC's DHCP] Server. I will not go into any of the reasons, as it does not matter for this material, and is highly dependent on your situation. The code below should allow you to enable netbooting for your Macs in such a manor that allows you to serve multiple images, that can be selected in firmware at the alt/option-boot menu. == What does this page assume? == * You already have a working ISC DHCP Server setup, and want to expand it for serving up netboot images via [http://en.wikipedia.org/wiki/Boot_Service_Discovery_Protocol BSDP]. * You already have a server that will hold the netboots (either the same server as DHCP, or another, does not matter). == My Testing Environment == * Internet Systems Consortium DHCP Server 4.2.3-P2 Gentoo-r0 * (work issued) Apple MacBookPro6,2, Purchased Fall 2010 == The Code == * This presents two images to the Alt/Option Boot menu: ** ID: 137, Name: DOE-Image (Also our default image) ** ID: 138, Name: DSR-NB01012012-05122012 * Sets ID 137 to be the Default Image for only holding down N at boot * Placed between global options and your subnet definitions, this is then enabled for all subnets (Will explore narrowing this down shortly) <syntaxhighlight lang="bash" line="GESHI_NORMAL_LINE_NUMBERS"> class "Apple-Intel-Netboot" { # Limit this class to only Intel Apple machines match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386"; option dhcp-parameter-request-list 1,3,17,43,60; # Send these options to the client (possibly forcing it, if the client didn't request it) # From: http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml # 1 - Subnet Mask # 3 - Router # 17 - Root Path # 43 - Vendor Specific # 60 - Class ID if (option dhcp-message-type = 8) { # on DHCPInform Messages, Us/Our (Server), Them (Client) option vendor-class-identifier "AAPLBSDPC"; # Let Them know we're responding with Apple BSDP Information if (substring(option vendor-encapsulated-options, 0, 3) = 01:01:01) { log(info, "BSDP_LIST"); # BSDP List # Let Them know this is the let, what server, the server's priority, what Our default image is, and provide the image list option vendor-encapsulated-options 01:01:01: # Start BSDP Inform/List Option 1 (01:), Length 1 (01:), Message Type List(1) (01:) 03:04: # BSDP option code 3 (length 04) -- Server Identifier 0A:00:03:02: # Server IP (10.0.3.2), Dec->Hex 04:02: # BSDP option code 4 (length 02) -- Server Priority 80:00: # Priority (32768) Dec->Hex 07:04: # BSDP option code 7 (length 04) -- Default Image ID 81:00:00:89: # Image ID - (137) Dec->Hex # This is what is picked as Default when you only hold down N on the client # # 81 breaks into: 0 or 8 for Non-Install (NetBoot) set or Install (NetInstal) set, # Most, including DeployStudio default to NetInstall set. # Then 0 for Mac OS 9, 1 for Mac OS X (Client) # 2 for OS X Server, and 3 for Hardware Diagnostics # 4- through 127 (x4:00-xf:ff) reversed for future use # And the last two are for the Image ID (Dec->Hex) # IDs 1-4095 (00:01-0F:FF) are for Server-Specific Images (You will probably want an ID in this range) # IDs 4096-65535 (10:00-FF:FF) Are "Globally-Unique", Multiple servers can present this same ID # and the client will only see one image, and pick a random(?) server to talk to. # 09: # BSDP option code 9 -- Boot image list 2A: # Length - =5*<numofimages>+<sumofallimagenames>, eg =5*2+(23+9), =10+32, =42, Dec->Hex =2A # This only appears once in the pacakge, no matter how many images you have below 81:00:00:89: # Image ID (137) -- dec->hex, see above (Default Image ID) for how to forumlate the full ID 09:44:6f:45:2d:49:6d:61:67:65: # Length(09):Name 'DoE-Image' ascii->hex 81:00:00:8A: # Image ID -- 138 17:44:53:52:2d:4e:42:30:31:30:31:32:30:31:32:2d:30:35:31:32:32:30:31:32; # Length(Hex:17,Dec:23):Name # Name: DSR-NB01012012-05122012 } elsif (substring(option vendor-encapsulated-options, 0, 3) = 01:01:02) { log(info, "BSDP_SELECT"); # BSDP Select, This is the client selecting which image they want to boot from # Here we basically do if statements to catch what image is referenced # Since we MIGHT be clustered, Check to see if we're the server being asked, this is BSDP Option 3 (Length 04) if (substring(option vendor-encapsulated-options, 9, 4) = 0A:00:03:02) { # Match to IP: 10.0.3.2, same as above. You'll want to change this log(info, "BSDP_SELECT-Responding, Client is talking to us."); # Log we're being talked to if (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:89) { # Catch Image ID 81:00:00:89 log(info, "BSDP_SELECT-Image: 137:DOE-Image"); # This isn't _needed_, but is nice for debugging/knowing # Insert stuff needed to boot here filename "/osx/i386/booter"; next-server 10.25.64.32; option root-path = "http://10.25.64.32/build.sparseimage"; } elsif (substring(option vendor-encapsulated-options, 15, 4) = 81:00:00:8A) { # Catch Image ID 81:00:00:8A log(info, "BSDP_SELECT-Image: DSR-NB01012012-05122012"); # Insert stuff here needed for boot # This example is from the FOG Project: http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server filename "macnbi-i386/booter"; #Replace 192.168.1.1 with the server's actual IP address. #Need clarification if NetRestore works for both Intel and PowerPC #For DeployStudio, either copy DeployStudioRuntime.sparseimage to /nbi, or use nfs share to connect to deploy studio server #option root-path "nfs:<deploystudio_ip>:/Volumes/<volume_label>/Library/NetBoot/NetBootSP0:<runtime_folder>/DeployStudioRuntime.sparseimage"; #option root-path "nfs:192.168.1.1:/nbi:DeployStudioRuntime.sparseimage"; option root-path "nfs:192.168.1.1:/nbi:NetInstall-Restore.dmg"; next-server 192.168.1.1; } else { log(info,"BSDP_SELECT-ERROR: Client responded with an image we don't have a match for! -- (Image added to list, but not in select catch?)"); } # End Image Selection Response } else { log(info,"BSDP_SELECT-Ignoring, Client is talking to another server--We're not worthy!"); # Log that we are not worthy of the client's time } # End Server Check } # End BSDP Options Check } # End DHCPInform Messages } # End Class </syntaxhighlight> == Caveats == * This does not present the netboot sets to the Startup Disk System Preferences Pane ** The SD Pref Pane does send out the proper BSDP List packet, however since there is already a DHCP Client listening on the default ports, the SD Pref Pane needs the response sent to another port (which is included in the packet), however I have not yet found a way for ISC DHCP to send to this other port when specified. When it gets the List packet, it responds, but to the DHCP Client, not the Pref Pane, hence it doesn't populate. * Would be enabled on all subnets handled by this DHCP server * Have not tested it working across DHCP-Relays or VLANs/IP-Helpers yet, however there should be nothing preventing it from working * All Netboot name lengths (plus 5bit overhead) combined need to be less then 255 characters (Reference Line 40 above), but you could have as many fit into that. I still want to test if you've hit that limit, if we can send another :09: list entry to include more entries (Say for very descriptive names...) * While this does have a catch for use in redundant/load balancing netboot servers, I haven't tested this yet. However, I don't see this working "As Designed" (or as a full replacement for Apple's dedicated BSDP Service). My thinking is explained next. * Any functionality that relies on the BSDP Server remembering a previously picked image will 'fail' back to the default. ** Apple's BSDP Server implements functionality that it will remember the last image that a client selected for boot. Along the same lines, there is also functionality built into it that will reduce the servers preference as it becomes loaded with clients, so then new clients go to other servers. I haven't yet tried to introduce either of these into ISC's DHCP server, however I don't see it being implemented easily. ** I say 'fail', as it doesn't fail, but the server only knows to hand over the default. * This will most likely not work with Diskless NetBoot Sets (or "Thin Client" sets), where the server holds a temp location for the client to write files back to **(Think booting a SIU Image, like one created by JAMF [https://jamfnation.jamfsoftware.com/article.html?id=64 Here]). This involves some Remapping and other funky stuff way beyond just setting up DHCP to handle netboots. == Resources Used to Complete this == * I basically took [http://bennettp123.com/post/22417766690/booting-imac12-1-from-isc-dhcp Bennett Perkin's work], whose work is based on others, and expanded upon it. * Used [http://easycalculation.com/decimal-converter.php EasyCalculation.com] for converting Dec->Hex, and Hex->Dec to verify (Image IDs and Lengths) * Used [http://www.dolcevie.com/js/converter.html Dolcevie.com] to convert ASCII/Strings to Hex (Image Names) * I originally got netbooting to work (without multiple images), using an [http://www.afp548.com/2006/12/20/howto-configure-gnulinux-to-provide-bsdp-netboot-services/ article on AFP548] * Also peaked at [http://fogproject.org/wiki/index.php?title=How_to_get_Macintosh%27s_Netboot_working_with_your_FOG_server FOG Project's recommendations] for getting Mac to Netboot * Verified DHCP Parameters with [http://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xml IANAs List] * Also read [http://opensource.apple.com/source/bootp/bootp-237.3/Documentation/BSDP.doc Apple's BDSP Documentation] about 20 different times == Fin == * <strike>Once OSXDeployment.com is out of Read-Only Maintenance mode, I will be posting this information there too (as it's more central for this kind of information). I will be keeping it here too, as my own reference.</strike> This site has been rolled into AFP548. * I have learned more about BSDP then I ever wanted to know :) * I am available on IRC if you have any questions or comments; irc.freenode.net, channel ##OSX-Server. My Nickname is Sedorox. 59efef303e514af5d19fc6eb6d57cf229946d1ae The World According to Apple 0 4 80 8 2014-05-31T01:34:47Z Bpenglase 1 wikitext text/x-wiki * [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images. * [[1]] - [[mw:Special:ExtensionDistributor/SyntaxHighlight_GeSHi]] 3fef09759062435b98efd989869864448ac1ac41 81 80 2014-05-31T01:37:48Z Bpenglase 1 wikitext text/x-wiki * [[Getting *nix to Netboot Macs]] - Using [http://www.isc.org/software/dhcp ISC DHCP] on almost any *nix system (linux, BSD, etc) to Netboot Macs, and offer multiple images. 386c8f5bd83f11c9535f79e31b35a02ffb997d18 Dabbling in Electronics 0 15 82 2014-06-08T00:44:25Z Bpenglase 1 Initial Page Creation wikitext text/x-wiki * [[ Raspberry Pi Projects ]] - Place for any of the projects I do using the Raspberry Pi * [[ BeagleBone Black Projects ]] - Place for any of the projects I do using the BeagleBone Black * [[ NavSpark Projects ]] - Place for any of the projects I do using the NavSpark/SkyTraq * [[ ATMega/Arduino Projects ]] - Place for any of the projects I do using an ATMega (or Arduino) 8c08af1674421128cc46c3215679a00d4747b0a5 NavSpark Projects 0 16 83 2014-06-08T01:02:28Z Bpenglase 1 Created page with "== NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark ] was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gn..." wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark ] was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". cb7399581a0f20c459ae39f5c9086f0655bdaff8 84 83 2014-06-08T01:02:52Z Bpenglase 1 /* NavSpark */ wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark] was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". 3f673269fffd9b07c1338e249922004fbbcbfe88 85 84 2014-06-08T01:05:30Z Bpenglase 1 Initial Page wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". I was luck and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices. I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location. Below I'll link in as I create projects that use this chip. dcbff140f4bd9bf02a40e4a8f2b275a8c0a7450a 86 85 2014-06-08T01:06:11Z Bpenglase 1 /* NavSpark */ wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". I was luck and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices. I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location. Below I'll link in as I create projects that use this chip. 4adbd4a2636aad398880c1ad11b83cef868d3294 87 86 2014-06-08T01:06:44Z Bpenglase 1 /* NavSpark */ wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". I was lucky and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices. I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location. Below I'll link in as I create projects that use this chip. 848e56000e926377e797bb0cb7c20bedf91cdfa5 88 87 2014-06-08T01:11:48Z Bpenglase 1 /* NavSpark */ wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". I was lucky and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices. I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location. Below I'll link in as I create projects that use this chip. == Projects == * [[NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi]] - Using one of the NavSpark modules, specifically the GPS+GLONASS one, use this with the NEMA Data and PPS to setup a Strat 1 NTP Time Source with the Raspberry Pi. 38833dc23c0fb88ac50ea22c68ee8dea5a338da7 97 88 2014-07-05T18:19:28Z Bpenglase 1 added BBB link wikitext text/x-wiki == NavSpark == If you haven't heard about the [http://www.navspark.com.tw SkyTraq NavSpark,] it was an [https://www.indiegogo.com/projects/navspark-arduino-compatible-with-gps-gnss-receiver IndieGoGo Crowd Funding Project] for an "Arduino Compatible with GPS GNSS Receiver". I was lucky and was able to get the early funding for two of these modules with active antennas. Quick props to these guys, as they kept everyone updated before shipping, as they were narrowing down antenna choices. I received mine the week of 06/02/14, and plan to use it more for a timing source, than navigation/location. Below I'll link in as I create projects that use this chip. == Projects == * [[NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi]] - Using one of the NavSpark modules, specifically the GPS+GLONASS one, use this with the NEMA Data and PPS to setup a Strat 1 NTP Time Source with the Raspberry Pi. Also now includes an RTC for keeping time between power cycles. * [[NavSpark GPS+GLONASS Stratum-1 NTP Time Source+RTC with a BeagleBone Black]] - Using one of the NavSpark modules, specifically the GPS+GLONASS one, use this with the NEMA Data and PPS to setup a Strat 1 NTP Time Source with the Raspberry Pi. Also includes an RTC for keeping time between power cycles. 4bf85bebfdc9a8aa99b92f84036bfabb91030ae1 NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi 0 17 89 2014-06-08T01:22:24Z Bpenglase 1 Initial+Sections wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == e081d5d154e066930d5839290a7435978cd3b427 90 89 2014-06-08T02:09:52Z Bpenglase 1 wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git 9abdd67490fd5bf59265737301162082de154905 91 90 2014-06-08T02:33:50Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s e4b1f5ce4d90bcf4b2334a1ba92954055aa214ef 92 91 2014-06-08T02:48:04Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev Patch Kernel: http://ntpi.openchaos.org/pps_pi/ 251bc7be4dd3d8b026a63a5141647a7093e49097 93 92 2014-06-08T15:36:37Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc Patch Kernel: http://ntpi.openchaos.org/pps_pi/ cb9220e9967040c27ba8c815406d3d739a016cb0 94 93 2014-06-08T15:48:30Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc Patch Kernel: http://ntpi.openchaos.org/pps_pi/ Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver 595bdb2cd613aeb749217213400040f30565db34 95 94 2014-06-08T15:48:56Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc Patch Kernel: http://ntpi.openchaos.org/pps_pi/ Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html 176a93b1e36f1c45dca6ad655207fd22b9fd72ef 96 95 2014-06-09T01:52:44Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc Patch Kernel: http://ntpi.openchaos.org/pps_pi/ edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html Uninstall existing ntp, compile/install latest ntp 683fc8427e89aba9e42eabb950247ea5bdee377f 99 96 2014-08-17T03:56:43Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git Patch Kernel: http://ntpi.openchaos.org/pps_pi/ Custom PCB uses GPIO23 Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger? apt-get install pps-tools apt-get install snmp apt-get install libcap-dev Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin #https://support.ntp.org/bin/view/Dev/Cross-compilingNTP Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp c4a3db182d15b595628fbbf420d721f42ea90f19 100 99 2014-08-17T06:01:52Z Bpenglase 1 wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html Update Pi apt-get update apt-get distupgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git Patch Kernel: http://ntpi.openchaos.org/pps_pi/ Custom PCB uses GPIO23 Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger? Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d ##rm K05hwclock.sh ln -s ../init.d/hwclock.sh S10hwclock.sh update-rc.d hwclock.sh enable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 1df07f62a14428840c4e6c6f3c891a407aa80bc8 NavSpark GPS+GLONASS Stratum-1 NTP Time Source+RTC with a BeagleBone Black 0 18 98 2014-07-05T18:20:16Z Bpenglase 1 Initial Layout wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == 4c3d44f4c7d8345f70e72ce09b6aaeb4a7c831e8 NavSpark GPS+GLONASS Stratum-1 NTP Time Source with a Raspberry Pi 0 17 101 100 2014-08-18T03:05:27Z Bpenglase 1 wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set root password Update Pi apt-get update apt-get distupgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git Patch Kernel: http://ntpi.openchaos.org/pps_pi/ Custom PCB uses GPIO23 Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger? Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp e5907f234bc89fadb621eec9539374c0571ce7ec 102 101 2014-10-13T02:18:32Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set root password Update Pi apt-get update apt-get distupgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) edit /etc/inittab, remove serial console crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git Patch Kernel: http://ntpi.openchaos.org/pps_pi/ Custom PCB uses GPIO23 Boot Options -> Default Kernel Command String: Remove console=ttyAMA0,115200, unless you want for troubleshooting, recommend to leave debugger? Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp eb7eded28692f9119a2b153fb31bb56ff5381222 103 102 2014-10-17T02:49:01Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 67, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 52edbf41c077bdf489c1df60eb68f8fdc5f1e8e4 104 103 2014-10-18T02:37:07Z Bpenglase 1 wikitext text/x-wiki == Intro == == What is this all about? == == What does this page assume? == == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 2d67a04da620fad7687dcce6e3e8772f0c713a73 105 104 2014-10-21T03:08:20Z Bpenglase 1 Starting layout for final page. wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 0e0d7cb9d587d20bdcd79b5f5e5b049bdcfaa2f0 106 105 2014-10-22T01:40:11Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator) == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp e0fdcea4d3a72243f41699313f70cf36596b2280 108 106 2014-10-22T01:42:58Z Bpenglase 1 added picture wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator) == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 9071a47e280534bd6c2c54846a630b4071086d22 109 108 2014-10-22T01:43:45Z Bpenglase 1 adjusted text/picture wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp e155b93051e714a23eee1302a78d7502e981920a 110 109 2014-10-22T01:44:20Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 7603d862a5d9030dceade78cbbfbeba0aab3b1fa 111 110 2014-10-22T01:44:45Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i^2c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i^2c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 9dd0e3b400356cfd6453d13bbf35654d19d1e15a 112 111 2014-10-22T01:47:22Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp de259705a78fd8df91fe702eccc61115bc9f72b9 113 112 2014-10-22T01:48:06Z Bpenglase 1 /* What does this page assume? */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 6626d3bfd36345837e51e8d911032e52f3554c19 114 113 2014-11-03T01:46:19Z Bpenglase 1 /* What does this page assume? */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Optional==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 9636abaf7c76472e3cc78c6202f600a640313585 115 114 2014-11-04T03:14:16Z Bpenglase 1 /* What does this page assume? */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set userpassword set hostname - NTP1 Change GPU memory to 16M (not used for NTP, more memory available to the system) Enable Kernel i2c Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get distupgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1)General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200"Device Drivers -> PPS Support (*)-> (*) PPS Client using GPIO-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set)Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2GPreemption Model -> No forced preemption (Server)CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 17727171e8ab8cc6608dc7af50ef597314bbdaf4 116 115 2015-02-15T07:04:33Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1) General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Deselect "Old Idle Dynticks Config" Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200" Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable? Edit arch/arm/mach-bcm2708/bcm2708.c line 282 - change gpio to pin 23 Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware edit /boot/config.txt add: kernel=Image-3187 Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ modprobe i2c-bcm2708 modprobe i2cdev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 200d21dcc6f88ade19551a50cf0ae736cca1f204 117 116 2015-02-15T07:26:22Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1) General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Deselect "Old Idle Dynticks Config" Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200" Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable? Edit arch/arm/mach-bcm2708/bcm2708.c line 282 - change gpio to pin 23 Custom PCB uses GPIO23 make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware edit /boot/config.txt add: kernel=Image-3187 Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 983f8557d7c07bd5d7e87d95cdad33364bee5a93 118 117 2015-02-18T02:10:09Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1) General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Deselect "Old Idle Dynticks Config" Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200" Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware edit /boot/config.txt add: kernel=Image-3187 dtoverlay=pps-gpio,gpiopin=<x> Custom PCB uses GPIO23 Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 6beea71ec7e7e31b054ed1385d0414306d1a0ee9 119 118 2015-02-19T23:40:57Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update reboot apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=<x> Custom PCB uses GPIO23 ====================================================================== OLD/INVALID edit /boot/cmdline.txt, remove serial references (AMA0) (only needed if you don't select to turn off serial console above) edit /etc/inittab, remove serial console (only needed if you don't select to turn off serial console above) KERNEL TIME Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig (Required!)General -> Default Hostname (NTP1) General -> Timers Subsystem -> Timer Tick Handling (Idle Dynticks System (Tickless Idle)) -> Periodic Timer Ticks (Constant rate, no dynticks) -- This is needed for NTP_PPSGeneral -> Deselect "Old Idle Dynticks Config" Boot Options -> Default Kernel Command -> Remove "console=ttyAMA0,115200" Device Drivers -> PPS Support (*)-> (*) PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install tar -cjf modules.tar.bz2 modtmp/ scp modules.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-31229 tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware edit /boot/config.txt add: kernel=Image-3187 ============================================================================================= Grab latest NTP from: http://www.ntp.org/downloads.html, for compile computer extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make now wait ~20minutes rm /var/lib/ntp/ntp.conf.dhcp if DHCP, static recommended ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device #Static IP Edit /etc/networking/interfaces iface eth0 inet static address netmask gateway #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp 6f0e208aa96847de3c868a756d448e6b32b135d6 120 119 2015-02-20T03:09:48Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 9248c7356b4e285e27397489b6d2c1fe7b4e911c 121 120 2015-02-20T03:14:33Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi (B or B+ preferred, since it has the wired network interface already on it) * You know how to wire/breadboard stuff to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations) * Setting up a cross-compile environment * Comfortable compiling and installing software/kernel * Comfortable applying patches == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 8ff21b79ecacaee795ea8529e381c26badc66679 122 121 2015-02-22T23:05:10Z Bpenglase 1 /* What does this page assume? */ Updated details about Pi models, and cleared up some phrasing, as well as re-worded some items due to differences in how the new kernel allows us to work with things. wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device af7758d30b0e83ccc9930a9cbd6be37f0b1eff20 123 122 2015-02-22T23:11:08Z Bpenglase 1 /* My Testing Environment */ Added Antenna link wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device d59e49da237c3ecca35a8498f16f8e46003990ca 124 123 2015-02-22T23:17:53Z Bpenglase 1 /* The Code */ Added intro wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 6d59697522db726ca21744c3212e93f4d3a816ad 125 124 2015-02-22T23:49:38Z Bpenglase 1 Added section wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup> RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 3399bfcbf1b3214bd30fd0a3db892f55c8e49a09 126 125 2015-02-22T23:50:06Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup> RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 506e41d552213bf79fae5e1547a71d1250bfcb7e 127 126 2015-02-22T23:50:33Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup> RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device c67d918bef33687628763e961de2cd21a48bdfab 128 127 2015-02-22T23:50:54Z Bpenglase 1 wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup> RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 506e41d552213bf79fae5e1547a71d1250bfcb7e 129 128 2015-02-22T23:51:20Z Bpenglase 1 /* Physical Connections */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device e727ab44a8ac461b7816e303139e03c29cb5ac6d 130 129 2015-02-22T23:51:53Z Bpenglase 1 /* Physical Connections */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPD RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 680697d07fac15fbd3bd2a8ee3783b2f3d279668 131 130 2015-02-23T00:01:43Z Bpenglase 1 /* Physical Connections */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device ca46a0c0b74dd8e7288fbfcd7429faaa1d33c726 132 131 2015-02-23T00:22:51Z Bpenglase 1 /* The Code */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device ce48ba4694141b4887f5a11815381385994a7630 133 132 2015-02-23T00:37:46Z Bpenglase 1 /* The Code */ Added details... wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 17e852a9777e67217504d2b0c3502066d322d887 134 133 2015-02-23T00:40:22Z Bpenglase 1 /* The Code */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device bbe9fd128c09eb5b1c201863b9e4a4404749559e 135 134 2015-02-23T01:18:24Z Bpenglase 1 /* The Code */ Code for cross-compile and kernel compiling. wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device d0ff4f2efbd48dad01369c14ad6e3103cbe035df 136 135 2015-02-23T02:31:57Z Bpenglase 1 /* The Code */ Finished entering steps! wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi: * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download mkknlimg<ref name"mkknlimg">[https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg]</ref> * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download knlinfo <ref name"knlinfo">[https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo]</ref> and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPs & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device f581efa467e861c86f5d84d52d0222ca336b7554 137 136 2015-02-23T02:33:18Z Bpenglase 1 /* Building the kernel */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download mkknlimg<ref name"mkknlimg">[https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg]</ref> * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download knlinfo <ref name"knlinfo">[https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo]</ref> and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPs & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 70f8d096001c7e01eebd5b066f10eda7c0ea344e 138 137 2015-02-23T02:34:53Z Bpenglase 1 /* GPs & UDev Rules */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. These two don't like working with each other <ref name="ppsonpi">[https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi]</ref>. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the compiling<ref name="pikernel">[http://elinux.org/Raspberry_Pi_Kernel_Compilation]</ref>. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download mkknlimg<ref name"mkknlimg">[https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg]</ref> * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download knlinfo <ref name"knlinfo">[https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo]</ref> and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 67641ec8890fc86e12fc8be8c7c6aec0531949bf 139 138 2015-02-23T02:42:19Z Bpenglase 1 /* Kernel Time */ Formatting issues. wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 9e127b6dff390d6ad5c7a0b071ae57a1d3f2485b 140 139 2015-02-23T02:47:50Z Bpenglase 1 /* ntp.conf Configuration */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf. We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason). driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device f32dd2dcd61292f171d509892d25db158277736f 141 140 2015-02-23T02:51:30Z Bpenglase 1 /* Resources Used to Complete this */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf. We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason). driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == Here's some sites I used, in no specific order. Some are referenced inline above, others are not. * http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html * http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html * https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi * http://elinux.org/Raspberry_Pi_Kernel_Compilation * https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md * http://ntpi.openchaos.org/pps_pi/ * http://www.catb.org/gpsd/gpsd-time-service-howto.html * http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 * https://support.ntp.org/bin/view/Dev/Cross-compilingNTP == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device 1397bb66cc5cf10686b951e9e7b69556bbbcee21 142 141 2015-02-23T03:01:29Z Bpenglase 1 /* Intro */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it. Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf. We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason). driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == Here's some sites I used, in no specific order. Some are referenced inline above, others are not. * http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html * http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html * https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi * http://elinux.org/Raspberry_Pi_Kernel_Compilation * https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md * http://ntpi.openchaos.org/pps_pi/ * http://www.catb.org/gpsd/gpsd-time-service-howto.html * http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 * https://support.ntp.org/bin/view/Dev/Cross-compilingNTP == Fin == == Random Notes (The building blocks) == http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html set user password Advanced options -set hostname - NTP1 -Change GPU memory to 16M (not used for NTP, more memory available to the system) -Enable Kernel i2c -Disable Kernel/Shell over Serial finish, reboot. login as pi sudo -s set root password Update Pi apt-get update apt-get dist-upgrade rpi-update apt-get install pps-tools snmp libcap-dev i2c-tools Yay device-Tree -- Reference: http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html edit /boot/config.txt: add -- dtoverlay=pps-gpio,gpiopin=23 Custom PCB uses GPIO23 dtoverlay=i2c-rtc,ds3231 Enables the DS3231 i2c clock at boot. reboot Upon reboot, you should see things like this toward the end of the kernel messages: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) KERNEL TIME Reason to compile is default kernel has NO_HZ enabled, and because of that, does not have CONFIG_NTP_PPS, for the kernel to sync to PPS. See: https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi Recommend to compile kernel on another system --http://elinux.org/Raspberry_Pi_Kernel_Compilation Build Machine crossdev -S -v -t arm-unknown-linux-gnueabi export CCPREFIX=arm-unknown-linux-gnueabi- may need gcc-config to set current version if updated get kernel source: git clone --depth 1 git://github.com/raspberrypi/linux.git pikern grab default /proc/config.gz from Pi, uncompress and copy to pikern/.config make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig General -> Timers Subsystem -> Deselect "Old Idle Dynticks Config"Device Drivers -> PPS Support -> Enable: PPS Kernel Consumer Support (Will not show up if the timer subsystem options above are not set) make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 mkdir modtmp make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress files tar -cjf modules.tar.bz2 modtmp/ tar -cjf dts.tar.bz2 arch/arm/boot/dts/ Transfer Files scp modules.tar.bz2 root@ntp1:~/ scp dts.tar.bz2 root@ntp1:~/ scp arch/arm/boot/Image root@10.0.3.14:/boot/Image-3187 Extract and move modules tar -xjf modules.tar.bz2 mv /lib/modules/<version> /lib/modules/<version>-orig mv modtmp/lib/modules/<version> /lib/modules cp -R modtmp/lib/firmware/* /lib/firmware extract and move DTB's tar -xjf dts.tar.bz2 cp arch/arm/boot/dts/*.dtb /boot/overlays mv /boot/overlays/bcm*.dtb /boot Need to sign kernel: https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md (Section 4.1) grab mkknlimg(https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg), and sign the kernel: mkknlimg /boot/Image-3187 /boot/Image-3187S grab knlinfo(https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo) and verify: knlinfo /boot/Image-3187S Should show something like: ./knlinfo /boot/Image-3187S Kernel trailer found at 8697996/0x84b88c: KVer: "Linux version 3.18.7+ (root@XXXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #1 PREEMPT Thu Feb 19 20:30:48 EST 2015" DTOK: true Edit /boot/config.txt, add: kernel=Image-3187S Configuring NTP Grab latest NTP from: http://www.ntp.org/downloads.html, extract ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl make && make install now wait ~20minutes Configure network: #Static IP Edit /etc/networking/interfaces iface eth0 inet static address 10.10.10.10 netmask 255.255.255.0 gateway 10.10.10.1 rm /var/lib/ntp/ntp.conf.dhcp GPS/UDEV Rules create /etc/udev/rules/09-gps.rules file contents: # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" Edit /etc/ntp.conf enable calibrate enable kernel # GPS Module server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 fudge 127.127.20.0 time2 +0.1939 # PPS of GPS Module server 127.127.22.0 minpoll 4 fudge 127.127.22.0 flag3 1 Add other servers/peers, set one as prefer (needed to get PPS lock, see http://ntpi.openchaos.org/pps_pi/) Tune the offset http://www.catb.org/gpsd/gpsd-time-service-howto.html set timezone - rm /etc/localtime ln -s /usr/share/zoneinfo/America/New_York /etc/localtime edit /etc/default/hwclock HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 edit /etc/init.d/hwclock.sh, line 64, comment out if statement for udev The RTC isn't handled by udev, so this check needs to be removed. #http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 dpkg --purge fake-hwclock ##cd /etc/rcS.d update-rc.d hwclock.sh enable update-rc.d alsa-utils disable update-rc.d x11-common disable ## OLD apt-get install gpsd gpsd-clients python-gps edit /etc/defaults/gpsd start_daemon = true devices="/dev/ttyAMA0" flags -b -n stty -F /dev/ttyAMA0 115200 set base_baud before gpsd starts, scans faster. service gpsd enable reboot, confirm with cgps -s apt-get install libncurses5-dev bc edit modules, include pps-gpio Instead of gpsd - symlink /dev/ttyAMA0 to /dev/gps0, use 127.127.20.0 mode 82 in ntp config, adds GPS_NEMA driver Uninstall existing ntp, compile/install latest ntp ============= -> (*) PPS Client using GPIO Device Drivers -> Real Time Clock -> (*) Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSon RX-8025 (For RTC 3231 option below) (Optional)Kernel Features -> memory split -> 2G/2G Preemption Model -> No forced preemption (Server) CPU Power Management -> CPU Frequency Scaling -> Default CPU Freq Governor -> Performance OldKernel Patch Kernel: http://ntpi.openchaos.org/pps_pi/ - https://raw.githubusercontent.com/lampeh/rpi-misc/master/linux-pps/linux-rpi-pps-gpio-bcm2708.diff Note: Line numbers are different with newer kernel. Provide updated patch.... NewKernel >=3.18.x? Use DeviceTable - No patching =============================== ##Cross-compile NTP: ##mkdir tmpinstall##make -j2##make install ##tar -cjf ntp.tar.bz2 tmpinstall ##copy files out cp bin/ntpd bin/ntp-wait bin/ntptime /usr/sbin ##https://support.ntp.org/bin/view/Dev/Cross-compilingNTP ## RTC modules/i2c already enabled in kernel from above i2c-dev module i2cdetect -y 1 - verify on 68 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device Add after unset TZ in hwclock.sh modprobe i2c-bcm2708 modprobe i2c-dev modprobe rtc-ds1307 echo "ds3231 0x68" > /sys/class/i2c-adapter/i2c-1/new_device ad3f87dedaf3c955fb940244cec03b1a3f335907 143 142 2015-02-23T03:06:52Z Bpenglase 1 /* Random Notes (The building blocks) */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it. Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf. We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason). driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == == Resources Used to Complete this == Here's some sites I used, in no specific order. Some are referenced inline above, others are not. * http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html * http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html * https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi * http://elinux.org/Raspberry_Pi_Kernel_Compilation * https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md * http://ntpi.openchaos.org/pps_pi/ * http://www.catb.org/gpsd/gpsd-time-service-howto.html * http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 * https://support.ntp.org/bin/view/Dev/Cross-compilingNTP == Fin == b97d7f277cb92b5799d906b8ec89a8fc15444d05 144 143 2015-02-23T03:21:05Z Bpenglase 1 /* Caveats */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it. Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf. We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason). driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == This isn't perfect by any means. Between the GPS module not being meant for timing, to the ethernet being connected over USB which introduces delays and possibly jitter. Also temperature changes affect it (both the GPS module and RTC have Temperature Compensated crystals). There are many more precise solutions. Some of them you can even use with the Pi and modify it to be more precise. Barring the above, it's still better than relying on your PCs built in clock! == Resources Used to Complete this == Here's some sites I used, in no specific order. Some are referenced inline above, others are not. * http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html * http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html * https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi * http://elinux.org/Raspberry_Pi_Kernel_Compilation * https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md * http://ntpi.openchaos.org/pps_pi/ * http://www.catb.org/gpsd/gpsd-time-service-howto.html * http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 * https://support.ntp.org/bin/view/Dev/Cross-compilingNTP == Fin == c0b6fd508af15af6b49812a497ac20438ca39794 145 144 2015-02-23T03:25:02Z Bpenglase 1 /* Fin */ wikitext text/x-wiki == Intro == Here are my notes for getting a [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS] module working with a Raspberry Pi (Model B) for Timing/NTP purposes. They have since come out with a specific [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ timing module] that would probably be better suited for this. But alas, it's not what I have right now :) This idea isn't new or original. Obviously time servers have been around for a while. Since the Pi has come out, many people have linked GPS and the Pi together for a low cost time solution. This is my take on it. Keep in mind, that this is how I set mine up. There are many configurations and options that you can do with just the parts you see here. It can be more simplistic, or it can include a LOT more, and be really awesome. == What is this all about? == For a long time now, I've wanted to setup a [http://navspark.mybigcommerce.com/ns-t-precision-timing-mode-gps-receiver/ Stratum 1] time source. It allows better matching of logs for debugging, and allows a more accurate time source for local network devices. This page goes over the module, getting it wired up to a Pi, then getting the Pi working with the module. I've also added a i<sup>2</sup>c TCXO RTC ([http://www.maximintegrated.com/en/products/digital/real-time-clocks/DS3231.html DS3231]) for timekeeping while the unit does not have power. This was added as the Pi does not have an RTC built in, and it may take some time for the Pi to sync with peers and/or GPS to get time set. This will give me a time source on my network that is extremely accurate for my needs. I created a [https://www.oshpark.com/shared_projects/4I81CEbO custom PCB] for attaching the NavSpark module, DS3231, and associated parts to the Pi. This makes it nice and compact to put to the side to just run. Gives it a nice SAF. ([http://en.wikipedia.org/wiki/Wife_acceptance_factor Spouse Approval Factor]) == What does this page assume? == * You have a NavSpark (or similar) GPS Module that outputs RS232 TTL NEMA GPS code, as well as a 1PPS (Pulse per second) output. * You have a Raspberry Pi Model B Variant (Original, B+, or Pi 2 Model B should all work. However the B is recommended over the A variant due to the hardwire network.) * You know how to wire/breadboard to the Pi * Fresh install of Raspbian (either directly or through NOOBS) ====Other==== * Logic Level Converter - If your GPS module outputs 5v, as the Pi need 3v in. (Note: The NavSpark outputs 3v) * Solder * Soldering Iron * Materials in BOM below if using custom adapter board * Pi Case * Good, solid/stable output, 5v USB Power Supply (a good quality power supply can make a big difference, especially when used in timing situations. I happen to be using a HP TouchPad supply, as I have a few around.) * Set up a cross-compile environment. Highly recommended for recompiling the kernel. * Comfortable compiling and installing software/kernel == My Testing Environment == [[File:DevSetup.jpg|200px|thumb|left]] * [http://www.mcmelectronics.com/product/83-14421 Raspberry Pi Model B] * [http://www.mcmelectronics.com/product/83-14389 GPIO Breadboard Breakout] * [http://navspark.mybigcommerce.com/navspark-gl-arduino-compatible-development-board-with-gps-glonass/ NavSpark GPS+GLONASS Module] * [http://navspark.mybigcommerce.com/internal-gps-glonass-active-antenna/ Internal GPS/GLONASS Active Antenna] * [http://www.mouser.com/Search/ProductDetail.aspx?R=DS3231S%23virtualkey66880000virtualkey700-DS3231S%23 Maxim DS3231 i<sup>2</sup>c TCXO RTC (Temperature Compensated Oscillator)] == Physical Connections == The NavSpark module is referenced with the USB socket on the right side, GPS RF Connection on the left. For the NavSpark Module * Connect the first pin on the bottom row, closest to the USB socket, to the 5V power rail from the Pi. * Connect the fourth pin on the bottom row, moving away from the USB socket, to the GND rail from the Pi. * Connect the fourth pin on the top row, moving away from the USB socket, to the GPIO pin you are using for PPS (I use 23). * Connect the last pin on the top row, closest to the GPS RF U.FL connector, to the Serial RXD pin on the Pi. For the i<sup>2</sup>c RTC * Connect pin 2, with a capacitor to the 5V power rail from the Pi. * Connect pin 16 (SCL) to GPIO3 (SCL) on the Pi. * Connect pin 15 (SDA) to GPIO2 (SDA) on the Pi. * Connect pin 14 to a Battery, so it keeps time between power-cycles. * Connect pin 13 to GND rail from the Pi. Or optionally, use the PCB mentioned above, which makes all these connections for you, in addition to the i<sup>2</sup>c RTC. This does require soldering the components to the board. '''NOTE: This setup does not require the i<sup>2</sup>c 3v pull-up resistors, as the Pi provides that, however the PCB does have the pads for them, just in case.''' == The Code == You'll want to start with a fresh install of [http://www.raspberrypi.org/downloads/ Raspbian], Either directly, or from [http://www.raspberrypi.org/downloads/ NOOBS]. This makes sure you're on a even base. Once you have a fresh install, just follow the steps below. If you already have a tweaked install that you want to keep, just pick and choose the commands below that suit what you're trying to do. === Initial Setup === This picks up at first boot after Raspbian install. # Set Pi User Password # Under Advanced: ## Set Hostname: NTP1 ## Change GPU Memory to 16M (Not really used, normally headless) ## Enable Kernel i<sup>2</sup>c ## Disable Kernel/Shell over Serial # Select Finish and reboot # Login as Pi # sudo -s # passwd (Set root password) === Update & Tools Install === # apt-get update # apt-get dist-update # rpi-update # apt-get install pps-tools snmp libcap-dev i2c-tools === Add Boot Options === Edit /boot/config.txt, and add the following to the bottom Enable PPS over GPIO pin 23 * dtoverlay=pps-gpio,gpiopin=23 Enable i<sup>2</sup>c RTC DS3231 * dtoverlay=i2c-rtc,ds3231 Reboot, and during the following boot, you should see something similar to: [ 5.401032] pps_core: LinuxPPS API ver. 1 registered [ 5.506199] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> [ 5.638198] pps pps0: new PPS source pps.-1 [ 5.741468] pps pps0: Registered IRQ 417 as PPS source [ 5.822304] bcm2708_i2c_init_pinmode(1,2) [ 5.961135] bcm2708_i2c_init_pinmode(1,3) [ 6.260785] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0 [ 6.369424] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000) To verify the HWClock: * hwclock -r If you haven't set it yet, it may not return a proper value. Once we get NTP setup, you can set the HWClock, and this will return properly. To verify the PPS: * ppstest /dev/pps0 You should see output similar to trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1424653025.000001374, sequence: 74588 - clear 0.000000000, sequence: 0 source 0 - assert 1424653026.000000374, sequence: 74589 - clear 0.000000000, sequence: 0 source 0 - assert 1424653027.000000375, sequence: 74590 - clear 0.000000000, sequence: 0 source 0 - assert 1424653028.000001374, sequence: 74591 - clear 0.000000000, sequence: 0 If all was successful, Congrats, the system now sees the PPS and has a RTC! === Kernel Time === Now, the stock Pi kernel should work, however it is missing an option to tell the kernel itself to sync to the PPS Signal. This is the CONFIG_NTP_PPS kernel option. If you were to just go into menuconfig on the kernel, you won't see this however. That is because the kernel has the CONFIG_NO_HZ (tickless) system option set. [https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi These two don't like working with each other]. So, to overcome this, I highly recommend recompiling the kernel to set the proper options. It is highly recommended, due to the speed of the Raspberry Pi, that you setup another, faster, machine to do the [http://elinux.org/Raspberry_Pi_Kernel_Compilation compiling]. This will probably not be an ARM system, so you'll want to setup CrossCompiling. I use a Gentoo system, so I'm going to base setting up the crosscompile system using commands available in Gentoo. ==== Cross Compiling ==== Install crossdev, if you already haven't * emerge crossdev Install the arm environment * crossdev -S -v -t arm-unknown-linux-gnueabi If you already have both of these installed, verify your build environment with gcc-config. Use "gcc-config -l" to list the environments, and then "gcc-config set <number>" the appropriate ARM version Export a variable to make the commands easier * export CCPREFIX=arm-unknown-linux-gnueabi- Grab the latest Raspberry Pi Kernel into the 'pikern' directory * git clone --depth 1 git://github.com/raspberrypi/linux.git pikern cd to the pikern directory for the rest of the compiling Get the config.gz file from /proc on your Pi, and transfer it to your build machine's pikernel directory. Then uncompress it to the kernel config * zcat config.gz > .config Tell the kernel to use the existing config (This shouldn't prompt you for anything, but if it does, it means there are newer options in the kernel you are compiling, than the current running kernel. Answer as you desire.) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig ===== Configure the kernel ===== Enter the kernel's menuconfig system * modify kernelmake ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig Change the following options * General Setup ** Timers subsystem *** Change "Timer tick handling" to "Periodic timer ticks (constant rate, no dynticks)" *** Deselect "Old Idle Dynticks Config" (CONFIG_NO_HZ) * Device Drivers ** PPS Support *** Select "PPS Kernel Consumer Support" (CONFIG_NTP_PPS) Optional, but I would also change the CPU Frequency Governor to Performance * CPU Power Management ** CPU Frequency Scaling *** Change "Default CPUFreq Governor" to "Performance" *** Deselect Powersave, Userspace, Ondemand, and Conservative Note: Personally I like a kernel that doesn't really have modules, and only uses the options that are needed. This also reduces compile time, as not everything is built. Because of this, I have pruned down a kernel config and modified it to suite the more basic timekeeping, and less user interactive. This will be available here. Now save and exit the menuconfig system. ===== Building the kernel ===== Now compile the kernel, and take a break (it takes a while....) * make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4 Once the kernel has compiled, create a temporary directory to 'install' the modules to: * mkdir modtmp Now 'install' the modules to that directory: * make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./modtmp modules_install Compress the modules for transfer to the Pi: * tar -cjf modules.tar.bz2 modtmp Compress the Device Tree files for transfer to the Pi: * tar -cjf dts.tar.bz2 arch/arm/boot/dts Transfer the files to the Pi (note: you'll probably want to use the IP address, instead of the hostname): * scp modules.tar.bz2 root@ntp1:~/ * scp dts.tar.bz2 root@ntp1:~/ * scp arch/arm/boot/Image root@ntp1:/boot/Image-New ===== Installing the kernel, modules, and Device Tree definitions ===== Now move to the pi for the following. This was done as the root user, since that's where the files were transferred to. Extract the modules * tar -xjf modules.tar.bz2 Move your current kernel's modules out of the way (At the time of writing, the kernels referenced are 3.18.7+) * mv /lib/modules/3.18.7+ /lib/modules/3.18.7+-old Move the new modules into place * mv modtmp/lib/modules/3.18.7+ /lib/modules Copy firmware * cp -R modtmp/lib/firmware/* /lib/firmware Extract the Device Tree files * tar -xjf dts.tar.bz2 Move the files where needed * mv arch/arm/boot/dts/*.dtb /boot/overlays * mv /boot/overlays/bcm*.dtb /boot ===== Kernel Trailer & Install ===== You will need to add a trailer to the kernel for it to boot and use the Device Tree successfully. Information about this can be found under [https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md Section 4.1]. Download [https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg mkknlimg] * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/mkknlimg -O mkknlimg Move the old kernel to the side * mv /boot/kernel.img /boot/kernel-old.img Sign the new kernel (which creates a new file, and we'll call it kernel.img!) * perl mkknlimg /boot/Image-3187 /boot/kernel.img Output should look like Version: Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015 DT: y If you want to verify the /boot/kernel.img file, download [https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo knlinfo] and run it * wget https://raw.githubusercontent.com/raspberrypi/tools/master/mkimage/knlinfo -O knlinfo * perl knlinfo /boot/kernel.img Output shoudl look like Kernel trailer found at 8317848/0x7eeb98: KVer: "Linux version 3.18.7+ (root@XXXXXXX) (gcc version 4.8.3 (Gentoo 4.8.3 p1.1, pie-0.5.9) ) #3 Sat Feb 21 23:06:15 EST 2015" DTOK: true Optional: Now if you reboot, it should boot with your kernel. You can verify by the buildtime from uname * uname -a Output should look like Linux NTP1 3.18.7+ #3 Sat Feb 21 23:06:15 EST 2015 armv6l GNU/Linux Note the matching build times to the trailers. If you don't do the signing, and just slap the kernel in place, it'll work, but you won't have any of the device tree stuff. This means the DTOverlay stuff you added to config.txt is ignored. === NTP === The stock install does include NTP. However, it does not include ATOM support, which is needed for PPS. So, we shall build our own! Now, I haven't figured out a way to cross-compile NTP and have it work on the Pi, so I just do all the building there. This also just installs over top of the Debian Package. Keep this in mind if you update your system and it updates NTP, it could revert your changes, and PPS will stop working (won't even show up in 'ntpq -p') Download the latest source from * http://www.ntp.org/downloads.html I recommend version 4.2.8 or higher. If you're brave, you can try the development track, 4.3.x. Extract (using example 4.2.8p1) & enter the directory * tar -xzf ntp-4.2.8p1.tar.gz * cd ntp-4.2.8p1 ==== Configuring & Building NTP ==== Configure NTP with the options you would like. I chose the following to suite me. Namely ATOM, native NMEA, and GPSD, SHM, and WWV for possible later use. I also enable SNMP, IPv6, and some other options needed for it to work right with the kernel (linuxcaps and clockctl) * ./configure --prefix=/usr --enable-ATOM --enable-NMEA --enable-GPSD --enable-SHM --enable-WWV --with-ntpsnmpd --enable-ipv6 --enable-linuxcaps --enable-clockctl This will take some time. Well over 20 minutes I believe. Once this is done, build NTP, and install it * make && make install ==== ntp.conf Configuration ==== Add (or adjust) the following settings to your ntp.conf. We're basically adding the server configurations for the GPS/NMEA and PPS. Also, you want to configure some other NTP servers to sync against, as the GPS time tends to be off/drift. The more the better. If you only sync with one or two, you'll have what happened a few years ago, where if that time gets off, and you only have a limited selection to pick from, you trust the wrong time. This lead to some interesting problems. So... select as many as you want (within reason). driftfile /var/lib/ntp/ntp.drift enable calibrate enable kernel # Enable this if you want statistics to be logged. statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). #server ntp.your-provider.example # GPS Module via NMEA server 127.127.20.0 mode 82 minpoll 4 maxpoll 6 prefer fudge 127.127.20.0 flag1 1 flag2 0 flag3 1 time2 +0.2100 # PPS of GPS Module server 127.127.22.0 minpoll 1 maxpoll 1 fudge 127.127.22.0 flag3 1 # Some Pool servers, from different sub-pools as well # General NTP Pool (mainly for IPv6) server 2.pool.ntp.org # General US NTP Pool server 0.us.pool.ntp.org server 1.us.pool.ntp.org # Gentoo NTP Pool server 0.gentoo.pool.ntp.org # pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will # pick a different set every time it starts up. Please consider joining the # pool: <http://www.pool.ntp.org/join.html> server 3.debian.pool.ntp.org server 2.debian.pool.ntp.org The rest of the config goes on about access control. The defaults are (now) fairly restrictive, and only allow time requests. So anyone can set time against this server. Adjust this as needed, but don't make it too open. Also, as noted on the Debian pool comments, if you set this up, please consider [http://www.pool.ntp.org/join.html joining the NTP Pool]. === Networking === I highly recommend setting a static IP address. Generally, you want all your machines on the network to use this device as it's timesource. You don't want it changing IPs on you. Edit /etc/network/interfaces Change the line 'iface eth0 inet dhcp' to be something like (to support both IPv4 and IPv6 Static) iface eth0 inet static address 10.10.10.2 netmask 255.255.255.0 gateway 10.10.10.1 iface eth0 inet6 static address 2001:db8::10 netmask 64 gateway 2001:db8::1 '''If you use DHCP, make sure to remove "ntp-servers" out of the 'request' field in /etc/dhcp/dhclient.conf''' === GPS & UDev Rules === Edit/Create file /etc/udev/rules/09-gps.rules with the following information # Adds symlink from serial interface to /dev/gps0 for ntpd KERNEL=="ttyAMA0", SYMLINK+="gps0" As noted by the comment, this adds the symlink to /dev/gps0 for NTP to pick up on. === Timezone === What's a good timekeeping box without the correct timezone? Remove the existing file /etc/localtime * rm /etc/localtime Link in your correct timezone (I use New_York) * ln -s /usr/share/zoneinfo/America/New_York /etc/localtime === Configuring HW Clock === Edit /etc/default/hwclock and uncomment the following: HWCLOCKACCESS=YES HCTOSYS_DEVICE=rtc0 Edit /etc/init.d/hwclock.sh and make the following changes: Starting at line 64, you want to COMMENT out the following check for udev. If you don't, the clock fails to set at startup. So it should look something like this, with added comment #i2c RTC doesn't rely on udev, so this will fail out if left in. #if [ -d /run/udev ] || [ -d /dev/.udev ]; then #return 0 #fi You now have a Hardware clock, so get rid of the pesky fake hardware clock * dpkg --purge fake-hwclock Now enable hwclock.sh at boot * update-rc.d hwclock.sh enable While you're at it, disable X11-common and alsa-utils from starting. Not needed. * update-rc.d alsa-utils disable * update-rc.d x11-common disable === Finished === Now with any luck, you can reboot the system, and it will come back with it's static IP, several other NTP sources configured, and then sync to PPS. You can verify all this with ntpq -p * ntpq -p Output similar to: remote refid st t when poll reach delay offset jitter ============================================================================== xGPS_NMEA(0) .GPS. 0 l 14 16 377 0.000 -96.765 8.635 oPPS(0) .PPS. 0 l 5 8 377 0.000 0.000 0.004 -taranis 209.51.161.238 2 u 50 64 377 0.506 2.603 0.108 -blue.1e400.net 91.189.89.199 3 u 50 64 377 15.990 1.320 6.374 -fairy.mattnordh 200.98.196.212 2 u 12 64 377 30.491 3.736 0.197 *74.117.238.11 ( 1.80.17.144 3 u 27 64 377 34.860 2.174 1.333 -209.118.204.201 149.20.64.28 2 u 3 64 377 87.911 4.254 1.502 == Caveats == This isn't perfect by any means. Between the GPS module not being meant for timing, to the ethernet being connected over USB which introduces delays and possibly jitter. Also temperature changes affect it (both the GPS module and RTC have Temperature Compensated crystals). There are many more precise solutions. Some of them you can even use with the Pi and modify it to be more precise. Barring the above, it's still better than relying on your PCs built in clock! == Resources Used to Complete this == Here's some sites I used, in no specific order. Some are referenced inline above, others are not. * http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html * http://www.satsignal.eu/ntp/Raspberry-Pi-quickstart.html * https://support.ntp.org/bin/view/Sandbox/HowtoPpsOnRaspberryPi * http://elinux.org/Raspberry_Pi_Kernel_Compilation * https://github.com/raspberrypi/documentation/blob/master/configuration/device-tree.md * http://ntpi.openchaos.org/pps_pi/ * http://www.catb.org/gpsd/gpsd-time-service-howto.html * http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=16218 * https://support.ntp.org/bin/view/Dev/Cross-compilingNTP == Fin == Overall, I'm very happy with how this turned out. Granted, some things could still be done to improve upon this, and maybe over time I will do those things. I do want to do the same setup with the BeagleBone Black, and see how it compares. I also have a Soekris Net4501 that I plan to throw into the mix as well. Also, it's another project complete, and documented! Woo! Did I mention you should consider [http://www.pool.ntp.org/join.html joining the NTP Pool]? If you can spare some Internets, I highly recommend it. 59126b309b2b4816ea1b8a515634c8112e145dde File:DevSetup.jpg 6 19 107 2014-10-22T01:41:40Z Bpenglase 1 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Computer Related Prodding 0 3 146 7 2015-03-05T04:05:12Z Bpenglase 1 wikitext text/x-wiki * [[The World According to Apple]] - Ways I have found to get OS X/iOS to function in the "Enterprise" world, typically with 3rd party software. * Breaking Windows - Different things I have found building Windows images and supporting Windows machines * [[Linux Things]] - Stuff being done in/with Linux (typically Gentoo). 129031394829eb3f9a6b0790c360b5ac4840dcb7 Linux Things 0 20 147 2015-03-05T04:06:09Z Bpenglase 1 Created page with "[[KVM/QEMU on Gentoo with Open vSwitch]]" wikitext text/x-wiki [[KVM/QEMU on Gentoo with Open vSwitch]] 2c92f2201f547d006ef02a474dec96da6bdaa165 KVM/QEMU on Gentoo with Open vSwitch 0 21 148 2015-03-05T04:07:38Z Bpenglase 1 Created page with "https://bbs.archlinux.org/viewtopic.php?id=179604 http://www.siliconloons.com/virtual-machines-on-fedora-17-with-open-vswitch/ http://www.siliconloons.com/fedora-17-with-open-..." wikitext text/x-wiki https://bbs.archlinux.org/viewtopic.php?id=179604 http://www.siliconloons.com/virtual-machines-on-fedora-17-with-open-vswitch/ http://www.siliconloons.com/fedora-17-with-open-vswitch/ http://wiki.gentoo.org/wiki/QEMU_with_Open_vSwitch_network http://blog.scottlowe.org/2012/11/07/using-vlans-with-ovs-and-libvirt/ http://ronnybull.com/2013/11/25/open-vswitch-on-gentoo-setting-up-your-first-vswitch/ http://libvirt.org/drvqemu.html http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf 8efc5951f80b232963c789b99a76bd28f54323fe Network & Systems Wrangling 0 6 149 74 2015-05-11T15:32:32Z Bpenglase 1 wikitext text/x-wiki * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). * [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. * [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. * [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics. * [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu. * [[Installing Windows over a Network]] - Installing Windows 7 Pro over the network, using iPXE, WIMBoot, and Samba. * [[Multicast Setup]] - Enabling Multicast on Cisco 3750 and 4500X to allow cross-subnet/building Video Transmission. 1618d3b8e9decde9b12ca9e19353d97d5b8afbb8 Multicast Setup 0 22 150 2015-05-11T15:42:11Z Bpenglase 1 Initial - Throwing links out. wikitext text/x-wiki ** http://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/rps.html#wp1029241 ** http://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/rps.html ** http://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst3750/software/release/12-2_37_se/configuration/guide/scg/swmcast.html ** http://www.cisco.com/c/en/us/support/docs/switches/catalyst-3750-series-switches/98289-pim-stub.html ** http://www.cisco.com/c/en/us/td/docs/ios/solutions_docs/ip_multicast/White_papers/rps.html#wp1029241 ** http://www.cisco.com/c/en/us/td/docs/ios/12_2/ip/configuration/guide/fipr_c/1cfmulti.html#wp1001103 ** http://nostringsattachedshow.com/2012/01/16/so-you-want-to-play-with-multicast-part-1/ ** http://www.cisco.com/c/en/us/support/docs/ip/ip-multicast/9356-48.html ee37749f72c58d6c057915e3999f5b35ffd1be1f Network & Systems Wrangling 0 6 151 149 2016-09-02T20:20:13Z Bpenglase 1 Added link for Supermicro 2028R-DE2CR24L wikitext text/x-wiki * [[Setup FreeRADIUS for 802.1x PEAP/MSCHAPv2 Auth against OpenLDAP]] - Setup FreeRADIUS to use OpenLDAP to authenticate 802.1x users for WPA2-Enterprise and EAPoL (Wireless and Wired authentication). * [[Setting up Cisco Switches for 802.1x Auth]] - Commands used to configure Cisco Switches to talk to a RADIUS server to do 802.1x authentication, with the bonus of dynamic VLAN assignment. * [[Setting up Cisco Access Points for 802.1x/WPA2-Enterprise Authentication]] - Commands used to configure Cisco Access Points to talk to a RADIUS server to do 802.1x/WPA2-Enterprise authentication, with the bonus of dynamic VLAN assignment. * [[PXE Booting and Utilities Menu]] - My home setup of a PXE Boot environment, to boot several MythTV Frontends, as well as offer utilities to machines for diagnostics. * [[IIS and ASP PXE Booting and Vesamenu]] - My work setup for a PXE Boot environment based on iPXE, PXELinux, and Vesamenu. * [[Installing Windows over a Network]] - Installing Windows 7 Pro over the network, using iPXE, WIMBoot, and Samba. * [[Multicast Setup]] - Enabling Multicast on Cisco 3750 and 4500X to allow cross-subnet/building Video Transmission. * [[Deploying a SuperMicro SuperStorage 2028R-DE2CR24L]] -- Setting up the 2028R-DE2CR24L for Windows Storage Spaces as a iSCSI SAN for VMware ESXi b165da160d4740dbbd48048bf15f4f201d92b6f1 Deploying a SuperMicro SuperStorage 2028R-DE2CR24L 0 23 152 2016-09-02T20:44:37Z Bpenglase 1 Initial page create and save. wikitext text/x-wiki https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm Quick Specs as ours is configured: 4x: Intel Xeon E5-2603 V4 (2 per node) 16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each) 2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node) 4x: MICRON 800GB S630DC 2.5" SAS 10x: SEAGATE 1.2TB SAS 10K PRM 51 2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node) Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf Block Diagram located on page 12. Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717. Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default) System power redundancy provided at 240V only. Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core). fa37aed8bfadec6813ddc1ca06af4b1a08ad2ba8 153 152 2016-09-03T21:46:56Z Bpenglase 1 wikitext text/x-wiki https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm Quick Specs as ours is configured: 4x: Intel Xeon E5-2603 V4 (2 per node) 16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each) 2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node) 4x: MICRON 800GB S630DC 2.5" SAS 10x: SEAGATE 1.2TB SAS 10K PRM 51 2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node) Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf Block Diagram located on page 12. Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717. Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default) System power redundancy provided at 240V only. Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core). Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/ Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression 712521a7106756d73a11e196d70babfbfb2fb20c 154 153 2016-09-04T04:32:17Z Bpenglase 1 wikitext text/x-wiki https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm Quick Specs as ours is configured: 4x: Intel Xeon E5-2603 V4 (2 per node) 16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each) 2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node) 4x: MICRON 800GB S630DC 2.5" SAS 10x: SEAGATE 1.2TB SAS 10K PRM 51 2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node) Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf Block Diagram located on page 12. Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717. Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default) System power redundancy provided at 240V only. Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core). Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/ Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression For iSCSI Failover Target Role, Delegate cluster to OU: http://morgansimonsen.com/2013/12/17/delegating-computer-object-management-tasks-2/ 9170dbd330213c6bd8953c4fbaaba2011771e88c 155 154 2016-09-05T01:10:09Z Bpenglase 1 wikitext text/x-wiki https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm Quick Specs as ours is configured: 4x: Intel Xeon E5-2603 V4 (2 per node) 16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each) 2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node) 4x: MICRON 800GB S630DC 2.5" SAS 10x: SEAGATE 1.2TB SAS 10K PRM 51 2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node) Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf Block Diagram located on page 12. Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717. Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default) System power redundancy provided at 240V only. Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core). Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/ Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression For iSCSI Failover Target Role, Delegate cluster to OU: http://morgansimonsen.com/2013/12/17/delegating-computer-object-management-tasks-2/ Replace failed disk: https://technet.microsoft.com/en-us/library/dn782852(v=ws.11).aspx 80af9ff0863dd44241e86fd1cc4bcd26cf15b87a 156 155 2016-09-06T17:54:42Z Bpenglase 1 wikitext text/x-wiki https://www.supermicro.com/products/system/2U/2028/SSG-2028R-DE2CR24L.cfm Quick Specs as ours is configured: 4x: Intel Xeon E5-2603 V4 (2 per node) 16x: SAMSUNG 8GB PC4-17000 2133MHz (8 per node for 64G each) 2x: SM SSD-DM128-SMCMVN1 128GB SAT (1 128G SATA DOM in each node) 4x: MICRON 800GB S630DC 2.5" SAS 10x: SEAGATE 1.2TB SAS 10K PRM 51 2x: MELLANOX CNTX3 E NTWK INTE CD, (1 - 2 port 10G SFP card per node) Manual: https://www.supermicro.com/manuals/superserver/2U/MNL-1876.pdf Block Diagram located on page 12. Diagram and product page indicate a Intel i210 Gigabit adapter that only links at 100mbit for Failover Heartbeat PCI-E 3.0 x8 node to node/NTB connectivity. Provided via PLX Technology PEX8717. Noted: PLX ExpressNIC SDK available from PLX. NDA required (Currently working on this, will update with any luck - Disabled in the Firmware by Default) System power redundancy provided at 240V only. Supermicro IPMI ISO Mount can only do ISOs at or less than 4.7G (standard DVD). Server DVDs provided by VLSC are too big (Includes Standard and Datacenter, each with full GUI and Core). Rebalancing + Updating: https://stebet.net/microsoft-finally-adds-rebalancing-to-storage-spaces/ Roles ans Features -> Datacenter Bridging, Enhanced Storage, Failover Clustering, Data Deduplication, FileServer, iSCSI Target server, iSCSI Target Storage Provider (VDS and VSS Hardware), Multipath IO, Remote Differential Compression For iSCSI Failover Target Role, Delegate cluster to OU: http://morgansimonsen.com/2013/12/17/delegating-computer-object-management-tasks-2/ Replace failed disk: https://technet.microsoft.com/en-us/library/dn782852(v=ws.11).aspx Enable iSCSI in Firewall. f8caebf5ec1a80a984d3391de91711fc97e44f16 Main Page 0 1 157 6 2017-07-08T20:37:58Z Bpenglase 1 Added Amateur Radio section wikitext text/x-wiki ''' Welcome. ''' Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work. * [[Computer Related Prodding]] * [[Network & Systems Wrangling]] * [[Dabbling in Electronics]] * [[Amateur Radio Meddling]] d68cf7307f285e552e54343d50587ef8ffbd897f 159 157 2022-05-28T01:10:34Z Bpenglase 1 Added HA wikitext text/x-wiki ''' Welcome. ''' Welcome to my little home on the Internet. Here I will post different things I've been up to. This can range from something to do with Electronics, to Tech Support, Sys Admin, or Net Admin work. * [[Computer Related Prodding]] * [[Network & Systems Wrangling]] * [[Dabbling in Electronics]] * [[Amateur Radio Meddling]] * [[Home Automation]] c1b6e582be56cb9caf4690c65a90a04c6f5ab201 Amateur Radio Meddling 0 24 158 2017-07-08T20:38:42Z Bpenglase 1 Initial! wikitext text/x-wiki The place where I'll eventually post stuff related to Amateur Radio... 3d3db6fd19f06b3fd30792b5c291bcc40e1766ce Home Automation 0 25 160 2022-05-28T01:13:59Z Bpenglase 1 Created page with "== Random Notes == Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US. This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncommen..." wikitext text/x-wiki == Random Notes == Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US. This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267 However you actually need to install the Gecko v3.2 SDK Firmware as of writing: C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.2\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7.16.3_297_EFR32ZG14_REGION_US.gbl Is then able to be written with the PC Controller. 7170771a136fc431ce150dfb5338d2ecbd33d347 161 160 2022-05-28T01:14:15Z Bpenglase 1 wikitext text/x-wiki == Random Notes == Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US. This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267 However you actually need to install the Gecko v3.2 SDK Firmware as of writing: C:\SiliconLabs\SimplicityStudio\v5\developer\sdks\gecko_sdk_suite\v3.2\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7.16.3_297_EFR32ZG14_REGION_US.gbl Is then able to be written with the PC Controller. 61daf3a3023f824b9556766771fd084341536f55 162 161 2022-05-28T02:24:10Z Bpenglase 1 wikitext text/x-wiki == Random Notes == Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US. This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267 More info here: https://github.com/kpine/zwave-js-server-docker/wiki/700-series-Controller-Firmware-Updates-(Linux) However you actually need to install the "Gecko SDK - 32bit and Wireless MCUs" (which at this time was 4.0.2) Firmware as of writing: C:\Users\<your windows user here>\SimplicityStudio\SDKs\gecko_sdk\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7_17_2_406_EFR32ZG14_REGION_US.gbl Is then able to be written with the PC Controller. d59b5b6852597a2da7b73edac837ddd2a89ea89c 163 162 2022-05-28T02:26:22Z Bpenglase 1 wikitext text/x-wiki == Random Notes == Updating SiLabs UZB-7 SLUSB001A USB Stick (EFR32ZG14) US. <s>This got me 90% there: https://github.com/zwave-js/node-zwave-js/discussions/2544#discussioncomment-1323267</s> More info here: https://github.com/kpine/zwave-js-server-docker/wiki/700-series-Controller-Firmware-Updates-(Linux) However you actually need to install the "Gecko SDK - 32bit and Wireless MCUs" (which at this time was 4.0.2) Firmware as of writing: C:\Users\<your windows user here>\SimplicityStudio\SDKs\gecko_sdk\protocol\z-wave\Apps\bin\gbl\ZW_SerialAPI_Controller_7_17_2_406_EFR32ZG14_REGION_US.gbl Is then able to be written with the PC Controller. 38242af2c18a3a1fde08736427a09d40a0f74f35